如何在sql server中使用group_concat进行查询[重复]
Posted
技术标签:
【中文标题】如何在sql server中使用group_concat进行查询[重复]【英文标题】:How to make a query with group_concat in sql server [duplicate] 【发布时间】:2013-07-09 14:43:27 【问题描述】:我知道在 sql server 中我们不能使用 Group_concat
函数,但这是我遇到的一个问题,我需要 Group_Concat
我的查询。我在谷歌上找到了一些逻辑但无法纠正它。我的 sql 查询是
select m.maskid,m.maskname,m.schoolid,s.schoolname,
md.maskdetail
from tblmask m join school s on s.id = m.schoolid
join maskdetails md on m.maskid = md.maskid
order by m.maskname ;
它给了我这样的结果
只需查看前 3 行,其中 maskid、maskname、schoolid、schoolname 相同,但 maskdetail 不同,因此想要一行,其中最后一列可以包含根据 maskid 的所有 maskdetail 等等。
我想要我的输出
等等。所以请在查询时帮助我。
提前致谢。
【问题讨论】:
自从将STRING_AGG
添加到 SQL Server 2017 以来,这不是关于 SQL Server 2005 的问题的重复相当,因此您可能需要调查一下,如果你有幸拥有最近的 SQL Server。
【参考方案1】:
查询:
SELECT
m.maskid
, m.maskname
, m.schoolid
, s.schoolname
, maskdetail = STUFF((
SELECT ',' + md.maskdetail
FROM dbo.maskdetails md
WHERE m.maskid = md.maskid
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM dbo.tblmask m
JOIN dbo.school s ON s.ID = m.schoolid
ORDER BY m.maskname
其他信息:
String Aggregation in the World of SQL Server
【讨论】:
hmmm 你能解释一下@Devart 我的意思是内部连接给出的结果就像图像中一样......所以将所有重复的 m.maskid , m.maskname , m.schoolid , s.schoolname 合并为一个我们需要分组的行tblmask
- maskdetails
= 1 to many
之间的关系,因此此处不应出现重复记录。
这里使用PATH(''), TYPE
和.value('.', 'NVARCHAR(MAX)')
的原因是什么,而不是@AmitSingh 的asnwer 中的简单PATH('')
?您的变体产生了一种方式,方式更重的执行计划,它是否有一些隐藏的优势来证明成本是合理的?如果不是,您会更正或修改您的答案,因为它已被接受并且应该是最好的吗?
好的,我知道了。 Amit Singh 的答案将返回 XML 编码的字符串(因为 for xml
选择的结果是一个 XML 文本/对象),因此,例如,<
将变成 &gt;
。而您的答案将逐字返回字符串,因为 value()
处理 XML 对象并从那里提取文本内容。
神奇的作品就像满足我的需要的魅力 +1【参考方案2】:
Select
A.maskid
, A.maskname
, A.schoolid
, B.schoolname
, STUFF((
SELECT ',' + T.maskdetail
FROM dbo.maskdetails T
WHERE A.maskid = T.maskid
FOR XML PATH('')), 1, 1, '') as maskdetail
FROM dbo.tblmask A
JOIN dbo.school B ON B.ID = A.schoolid
Group by A.maskid
, A.maskname
, A.schoolid
, B.schoolname
【讨论】:
+1。顺便说一下GROUP BY
这里不需要。【参考方案3】:
这也可以使用MSSQL 2008
中的Scalar-Valued Function
来实现
如下声明你的函数,
CREATE FUNCTION [dbo].[FunctionName]
(@MaskId INT)
RETURNS Varchar(500)
AS
BEGIN
DECLARE @SchoolName varchar(500)
SELECT @SchoolName =ISNULL(@SchoolName ,'')+ MD.maskdetail +', '
FROM maskdetails MD WITH (NOLOCK)
AND MD.MaskId=@MaskId
RETURN @SchoolName
END
然后你的最终查询会是这样的
SELECT m.maskid,m.maskname,m.schoolid,s.schoolname,
(SELECT [dbo].[FunctionName](m.maskid)) 'maskdetail'
FROM tblmask m JOIN school s on s.id = m.schoolid
ORDER BY m.maskname ;
注意:您可能需要更改函数,因为我不知道完整的表结构。
【讨论】:
另见:gooroo.io/GoorooTHINK/Article/10001/…【参考方案4】:请运行以下查询,在您的情况下它不需要 STUFF 和 GROUP BY:
Select
A.maskid
, A.maskname
, A.schoolid
, B.schoolname
, CAST((
SELECT T.maskdetail+','
FROM dbo.maskdetails T
WHERE A.maskid = T.maskid
FOR XML PATH(''))as varchar(max)) as maskdetail
FROM dbo.tblmask A
JOIN dbo.school B ON B.ID = A.schoolid
【讨论】:
STUFF 需要去掉第一个逗号,在你的情况下 maskdetail 以逗号结尾以上是关于如何在sql server中使用group_concat进行查询[重复]的主要内容,如果未能解决你的问题,请参考以下文章