在 SQL Server 中分组并在一列中连接记录
Posted
技术标签:
【中文标题】在 SQL Server 中分组并在一列中连接记录【英文标题】:Group by in SQL Server and concatenate records in one column 【发布时间】: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_price
和 Amount
列应该是 Max()。 balance
列是要支付的余额。如果客户支付全款,那应该是 0。
【问题讨论】:
【参考方案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】:您可以将STUFF
和GROUP BY
与MIN,MAX,SUM
聚合一起使用,如下所示,在您的示例中,paid amount is in 5 digit
和amount 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以上是关于在 SQL Server 中分组并在一列中连接记录的主要内容,如果未能解决你的问题,请参考以下文章