【问题标题】:Group by in SQL Server and concatenate records in one column在 SQL Server 中分组并在一列中连接记录
【发布时间】: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。

【问题讨论】:

    标签: sql sql-server view group-by


    【解决方案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
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-09
        • 2021-09-17
        • 1970-01-01
        • 2012-04-24
        • 2015-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多