如何使用 "Stuff and 'For Xml Path'" 合并 table 中的行

how to use "Stuff and 'For Xml Path'" to unite rows in table

请帮助我在 table 中获取以逗号分隔的统一行和帐户列表。我不太明白如何使用“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, quantity, price, summ, account) 
VALUES ('ty20210110', 3, 100, 300, 1002);
INSERT invoices(invoice, quantity, price, summ, account) 
VALUES ('ty20210110', 1, 250, 250, 1001);
INSERT invoices(invoice, quantity, price, summ, account) 
VALUES ('ty20210110', 2, 120, 240, 1002);
INSERT invoices(invoice, quantity, price, summ, account) 
VALUES ('ty20210110', 4, 100, 400, 1002);
INSERT invoices(invoice, quantity, price, summ, account) 
VALUES ('ty20210114', 3, 100, 300, 1001);
INSERT invoices(invoice, quantity, price, summ, account) 
VALUES ('ty20210114', 5, 80, 400, 1003);
INSERT invoices(invoice, quantity, price, summ, account) 
VALUES ('ty20210114', 5, 100, 500, 1004);


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

这是我得到的结果:

invoice summ accounts
ty20210110 200 1001,1002,1003,1004
ty20210110 240 1001,1002,1003,1004
ty20210110 250 1001,1002,1003,1004
ty20210110 300 1001,1002,1003,1004
ty20210110 400 1001,1002,1003,1004
ty20210114 300 1001,1002,1003,1004
ty20210114 400 1001,1002,1003,1004
ty20210114 500 1001,1002,1003,1004

这是我需要得到的结果:

invoice summ accounts
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,
             1,
             '') accounts
       FROM invoices i1
       GROUP BY i1.invoice;

对于 SQL Server 2017 及更高版本。

利用 STRING_AGG() 功能。唯一的细微差别是我们需要 select DISTINCT account 子查询中的值。

SQL

-- 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, 100, 300, 1002),
('ty20210110', 1, 250, 250, 1001),
('ty20210110', 2, 120, 240, 1002),
('ty20210110', 4, 100, 400, 1002),
('ty20210114', 3, 100, 300, 1001),
('ty20210114', 5, 80, 400, 1003),
('ty20210114', 5, 100, 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;

输出

+------------+------+----------------+
|  invoice   | summ |    accounts    |
+------------+------+----------------+
| ty20210110 | 1390 |      1001,1002 |
| ty20210114 | 1200 | 1001,1003,1004 |
+------------+------+----------------+