如何使用 "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 |
+------------+------+----------------+
请帮助我在 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 |
+------------+------+----------------+