问题描述
以下情况,pos / neg_text在重复:
这是我的反馈表:
id text-id pos_text neg_text cat_id
1 1 nice people null 21
2 1 nice people null 24
3 1 nice people null 27
4 1 null cold room 36
5 1 null cold room 37
我想将所有这些数据放到一行中,例如:
id text-id pos_text neg_text pos_cat_id neg_cat_id
1 1 nice people cold room "21,24,27" "36,37"
我的SQL查询应如何显示?我正在中间件中使用TypeScript实现算法来解决此问题,也许有DB专家可以通过简单的SQL查询来解决这个问题。
使用SQL Server 2008
解决方法
由于使用了旧版本的SQL Server,这并不容易。您缺少像CONCAT
这样的用于隐式转换的简单工具,而缺少像STRING_AGG
这样的较新的函数,这意味着您需要对表进行3次扫描才能实现1次扫描可以完成的工作。
相反,我们需要在此处使用“旧的” FOR XML PATH
方法来汇总值,并使用CONVERT
而不是简单的CONCAT(',',sq.catid)
。我使用3
作为长度,但是您可能需要更长的时间。
WITH YourTable AS(
SELECT *
FROM (VALUES(1,1,'nice people',null,21),(2,24),(3,27),(4,'cold room',36),(5,37))V(id,textid,postext,negtext,catid))
SELECT MIN(ID) AS ID,MAX(postext) AS postext,MAX(negtext) AS negtext,STUFF((SELECT ',' + CONVERT(varchar(3),sq.catid)
FROM YourTable sq
WHERE sq.textid = YT.textid
AND sq.postext IS NOT NULL
ORDER BY sq.id
FOR XML PATH(''),TYPE).value('(./text())[1]','varchar(MAX)'),'') AS poscatid,sq.catid)
FROM YourTable sq
WHERE sq.textid = YT.textid
AND sq.negtext IS NOT NULL
ORDER BY sq.id
FOR XML PATH(''),'') AS negtextid
FROM YourTable YT
GROUP BY YT.textid;
请注意,这是在最新版本的SQL中多么简单:
SELECT MIN(ID) AS ID,STRING_AGG(CASE WHEN postext IS NOT NULL THEN catid END,') WITHIN GROUP (ORDER BY ID) AS poscatid,STRING_AGG(CASE WHEN negtext IS NOT NULL THEN catid END,') WITHIN GROUP (ORDER BY ID) AS negcatid
FROM YourTable
GROUP BY textid;