如何使用“Stuff and 'For Xml Path'”来合并表中的行

问题描述

请帮助我在表格中获取以逗号分隔的联合行和帐户列表。我不太明白如何使用“Stuff and 'For Xml Path'”。

这是我的查询

CREATE TABLE invoices
(
invoice VARCHAR(20) NOT NULL,quantity INT NOT NULL,price INT NOT NULL,summ INT NOT NULL,account INT NOT NULL,);
INSERT invoices(invoice,quantity,price,summ,account) 
VALUES ('ty20210110',2,100,200,1001);
INSERT invoices(invoice,3,300,1002);
INSERT invoices(invoice,1,250,120,240,4,400,account) 
VALUES ('ty20210114',5,80,1003);
INSERT invoices(invoice,500,1004);


SELECT invoices.invoice,invoices.summ,accounts = STUFF(
             (SELECT disTINCT ',' + Convert(varchar,invoices.account,60) 
              FROM invoices
              FOR XML PATH ('')),'')
FROM invoices
GROUP BY invoices.invoice,invoices.summ

这是我得到的结果:

发票 summ 账户
ty20210110 200 1001,1002,1003,1004
ty20210110 240 1001,1004
ty20210110 250 1001,1004
ty20210110 300 1001,1004
ty20210110 400 1001,1004
ty20210114 300 1001,1004
ty20210114 400 1001,1004
ty20210114 500 1001,1004

这是我需要得到的结果:

发票 summ 账户
ty20210110 1390 1001,1002
ty20210114 1200 1003,1004

所以实际上我需要获取 2 张不同发票的金额,并用逗号指定涉及这些发票的帐户。

这里的 dbfiddle 也有这些东西:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=7a5de9e680693b5e70ea68cecebef6cc

提前谢谢你们。

解决方法

如果要求和,请不要按 summ 分组。在其上使用 sum()。并关联子查询。否则,您将获得所有帐户。

SELECT i1.invoice,sum(i1.summ) summ,stuff((SELECT DISTINCT
                     concat(',',i2.account)
                     FROM invoices i2
                     WHERE i2.invoice = i1.invoice
                     FOR XML PATH ('')),1,'') accounts
       FROM invoices i1
       GROUP BY i1.invoice;
,

对于 SQL Server 2017 及更高版本。

利用 fgets 函数。唯一的细微差别是我们需要在子查询中选择 STRING_AGG() account 值。

SQL

DISTINCT

输出

-- DDL and sample data population,start
DECLARE @invoices TABLE 
(
    invoice VARCHAR(20) NOT NULL,quantity INT NOT NULL,price INT NOT NULL,summ INT NOT NULL,account INT NOT NULL
);
INSERT @invoices(invoice,quantity,price,summ,account) VALUES 
('ty20210110',2,100,200,1001),('ty20210110',3,300,1002),250,120,240,4,400,('ty20210114',5,80,1003),500,1004);
-- DDL and sample data population,end

SELECT i1.invoice,SUM(i1.summ) AS summ,(
       SELECT STRING_AGG(account,') FROM 
       (
        (SELECT DISTINCT account FROM @invoices AS i2 WHERE i2.invoice = i1.invoice)
       ) AS x) AS accounts
FROM @invoices AS i1
GROUP BY i1.invoice;