在 SQL Server 中分组并在一列中连接记录

Posted

技术标签:

【中文标题】在 SQL Server 中分组并在一列中连接记录【英文标题】:Group by in SQL Server and concatenate records in one column 【发布时间】:2019-03-13 03:06:09 【问题描述】:

我有一个名为payment_data 的视图,其中包括数字、日期和字符串字段。

company | ref | Tag | event_date | sale_price | Amount  |  Receipt_No  | Paid  |   Balance

PRco Ltd| 123 | 0311| 03-10-2018 |  610000    | 610000  |  R19A0000761 | 50000 |   11000
PRco Ltd| 123 | 0311| 03-10-2018 |  610000    | 610000  |  R19A0000912 | 11000 |    0

这个表要分组得到如下结果

company | ref | Tag | event_date | sale_price | Amount  |  Receipt_No                |  Paid  |  Balance
PRco Ltd| 123 | 0311| 03-10-2018 |  610000    | 610000  |  R19A0000761, R19A0000912  | 61000  |    0  

表格按ref 列分组,Receipt_No 连接起来得到如上所示。 paid 列是聚合的,sale_priceAmount 列应该是 Max()。 balance 列是要支付的余额。如果客户支付全款,那应该是 0。

【问题讨论】:

【参考方案1】:

以下查询可帮助您获得所需的结果。创建的示例表供您参考,您可以根据需要使用视图。填充函数有助于连接收据编号

DECLARE @Payment_Data Table(
    Company VARCHAR(50), 
    Ref INT, 
    Tag INT, 
    Event_date DATE, 
    Sale_price INT, 
    Amount  INT,  
    Receipt_No VARCHAR(50), 
    Paid INT, 
    Balance INT)

INSERT INTO @Payment_Data  VALUES
('PRco Ltd',123,0311,'03-10-2018',610000,610000,'R19A0000761',500000,11000),
('PRco Ltd',123,0311,'03-10-2018',610000,610000,'R19A0000912',110000,0)


SELECT  Company, 
        Ref, 
        Tag, 
        max(Event_date), 
        max(Sale_price),
        MAX(Amount) amount,
        SUM(Paid) paid,
        (MAX(Amount)-SUM(Paid)) Balance,

        Receipt_No = STUFF((
          SELECT ',' + Receipt_No
          FROM @Payment_Data  p2
          WHERE ref = p2.ref
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

    FROM    @Payment_Data  p1
    GROUP BY Company, Ref, Tag

【讨论】:

知道了。谢谢你:)【参考方案2】:

它可以像下面这样使用GROUP BY

SELECT s1.company, 
       s1.ref, 
       s1.tag, 
       s1.event_date, 
       max(s1.sale_price)  sale_price, 
       max(s1.amount)  amount, 
       STUFF ((SELECT ', ' + CAST(receipt_no AS varchar(100))
                FROM 
                payment_data pd where pd.ref=s1.ref
                ORDER BY receipt_no
                FOR XML PATH('')
                ),1,2,'' ) AS Receipt_No,
       sum(s1.paid) paid ,
       min(s1.balance) balance
from payment_data s1
group by company,ref,tag,event_date

Online Demo

【讨论】:

【参考方案3】:

可以将STUFFGROUP BYMIN,MAX,SUM 聚合一起使用,如下所示,在您的示例中,paid amount is in 5 digitamount in 6 digit 不能平衡zero。在我的示例中,我制作了 6 digits paid amount 以匹配您的预期结果,但您应该更正并根据需要使用它

DECLARE @sales TABLE(company VARCHAR(50), 
    ref INT, 
    Tag INT, 
    event_date DATE, 
    sale_price INT, 
    Amount  INT,  
    Receipt_No VARCHAR(50), 
    Paid INT, 
    Balance INT)

INSERT INTO @sales VALUES
('PRco Ltd',123,0311,'03-10-2018',610000,610000,'R19A0000761',500000,11000),
('PRco Ltd',123,0311,'03-10-2018',610000,610000,'R19A0000912',110000,0)

SELECT s.company, 
    s.ref, 
    s.Tag, 
    s.event_date,
    MAX(s.sale_price) sale_price,
    MAX(s.amount) amount,
    MAX(s1.receipt) receipt,
    SUM(s.paid) paid,
    (MAX(s.amount)-SUM(s.paid)) balance
FROM @sales s
OUTER APPLY (
            select stuff(
                (select ',' + s1.Receipt_No 
                from @sales s1
                where s1.company = s.company
                AND s1.ref = s.ref
                AND s1.Tag = s.Tag
                AND s1.event_date = s.event_date
                for xml path('')
                )
            , 1, 1, '') receipt
        ) s1
GROUP BY s.company, s.ref, s.Tag, s.event_date

输出

company     ref Tag event_date  sale_price  amount  receipt                 paid    balance
PRco Ltd    123 311 2018-03-10  610000      610000  R19A0000761,R19A0000912 610000  0

【讨论】:

【参考方案4】:

您可以使用 group_concat 函数根据 Group by 进行连接。

SELECT  company, ref, Tag, sale_price, Amount, 
    dbo.GROUP_CONCAT(Receipt_No + ',' ) AS Receipt_No , sum(Paid)
FROM    dbo.foo
GROUP BY company, ref, Tag, event_date, sale_price, Amount

【讨论】:

错误的数据库 - 这是 sql-server

以上是关于在 SQL Server 中分组并在一列中连接记录的主要内容,如果未能解决你的问题,请参考以下文章

如何根据分组将字符串组合在一列中

如何在一列中对数据进行分组?

SQL:在一列中获取最小值和最大值

Azure 数据工厂在一列中映射 2 列

Power BI:将项目分组在一列中,具有不同值的其他列显示为几列

在一列中按多个值分组