sql-serverconcatenationfor-xml-pathstuff

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


Please help me to get united rows and list of accounts separated by commas in table. I don't quite understand how to use "Stuff and 'For Xml Path'" for it.

This is my query:

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

This is what I get in result:

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

This is what I need to get in result:

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

So actually I need to get sums for 2 different invoices and to specify accounts by commas which involved to those invoices.

Also have this stuff at dbfiddle here: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=7a5de9e680693b5e70ea68cecebef6cc

Thank You in advance guys.


Solution

  • Don't group by summ if you want to sum it. Use sum() on it. And correlate the subquery. Otherwise you'll just get all accounts.

    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;