如何在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 文本/对象),因此,例如,< 将变成 >。而您的答案将逐字返回字符串,因为 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进行查询[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 中使用 SQL 实现以下任务

如何在 SQL Server 中清理(防止 SQL 注入)动态 SQL?

如何在 SQL Server 中使用 Pivot

如何在 SQL Server 的 OVER 子句中使用变量

sql server 中如何插入一条时间记录

SQL Server:如何在更新语句中使用别名?