广告位联系
返回顶部
分享到

SQL Server实现group_concat功能的实例

MsSql 来源:互联网 作者:佚名 发布时间:2022-08-26 20:32:50 人浏览
摘要

一、实现 #tmp表内容如下: 实现group_concat的sql语句为: 1 2 3 4 5 6 7 8 9 10 11 12 Select RegionID, STUFF( ( SELECT , + T.c1 FROM #tmp T WHERE A.regionid = T.regionid FOR XML PATH() ), 1, 1, ) as group_concat FROM #tmp A

一、实现

#tmp表内容如下:

实现group_concat的sql语句为:

1

2

3

4

5

6

7

8

9

10

11

12

Select

  RegionID,

  STUFF(

       (

         SELECT ',' + T.c1

         FROM #tmp T

         WHERE A.regionid = T.regionid

         FOR XML PATH('')

       ), 1, 1, ''

     ) as group_concat

FROM #tmp A

Group by  RegionID

实现效果如下:

二、原理分析

2.1、FOR XML PATH的作用

FOR XML PATH 的作用是将查询结果集以XML形式展现,将多行的结果,展示在同一行,例如:

1

select c1 from #tmp where RegionID = 41653

其结果集如下:

1

select c1 from #tmp where RegionID = 41653 FOR XML PATH('')

当sql语句加上 FOR XML PATH('') 后,其结果集输出是:

具体输出的字符如下:

<c1>30.326809</c1><c1>30.327982</c1><c1>30.347933</c1><c1>30.388104</c1><c1>30.392830</c1><c1>30.367931</c1><c1>30.368052</c1><c1>30.367842</c1><c1>30.357318</c1><c1>30.357349</c1><c1>30.357349</c1>

通过字符拼接后可以把xml信息清除,并以指定的字符进行分割:

1

select ',' + c1 from #tmp where RegionID = 41653 FOR XML PATH('')

此时已基本达到group_concat的效果,但第一个字符串有分隔符需要去掉。

2.2、STUFF函数

2.2.1、STUFF函数在本SQL的作用

我们使用STUFF函数的目的是把第一个分隔符去掉。先看看效果:

上图可以看到,STUFF函数把字符串“abcdefg”中的第一个字符“a”删除。

使用该函数我们可以很轻松的把上图得到的结果集去掉第一个逗号分隔符:

需要详细了解STUFF函数可继续看该函数的语法,没兴趣的可以忽略。

2.2.2、STUFF函数语法

STUFF函数的作用是将字符串插入到另一个字符串中。它从第一个字符串的开始位置删除指定长度的字符,然后将第二个字符串插入到第一个字符串的开始位置。其语法为:

1

STUFF(character_expression , start , length , replaceWith_expression)

character_expression:字符数据的表达式,可以是常量、变量,也可以是字符列或二进制数据列。

start:一个整数值(从1开始),指定删除和插入的开始位置。start的类型可以是bigint。

  • 如果 start 为负或为零,则返回空字符串。

  • 如果 start 的长度大于第一个 character_expression,则返回空字符串。 

length:一个整数,指定要删除的字符数。length的类型可以是 bigint。

  • 如果 length 为负,则返回空字符串。

  • 如果 length 的长度大于character_expression,则最多可以删除到character_expression 中的最后一个字符。

  • 如果 length 为零,则不删除字符直接在指定位置插入内容。 

replaceWith_expression:字符数据的表达式,可以是常量、变量,也可以是字符列或二进制数据列。此表达式从 start 开始替换 length 个字符的character_expression。

  • 如果 replaceWith_expression 为 NULL,则在不插入任何内容的情况下删除字符。

2.3、sql语分分析

2.3.1、一个简单的group by

1

2

3

Select RegionID

FROM #tmp A

Group by RegionID

这个sql各位看官都十分熟悉,已经没什么好说的了。

2.3.2、在select语句后面加上子查询

1

2

3

4

5

6

7

8

9

Select RegionID,

    (

      SELECT ',' + T.c1

      FROM #tmp T

      WHERE A.regionid = T.regionid

      FOR XML PATH('')

    )

FROM #tmp A

Group by RegionID

在上述简单的group by语句基础上加入一个select里的子查询,其结果如下:

在该子查询中,当外层的group by返回结果集中的第一行RegionID为41653时,这个值被子查询的where条件所使用,相当于:

1

2

3

4

SELECT ',' + T.c1

FROM #tmp T

WHERE T.regionid = 41653

FOR XML PATH('')

因为FOR XML PATH把多行记录打平成一条记录,因此此时的返回结果为:

接着第group by返回结果集中的第二行45761传入该子查询,依次类似上面描述的执行,直到所有外层的值遍历完成。

2.3.3、去掉子查询结果集的第一个分隔符

1

2

3

4

5

6

7

8

9

10

11

12

Select

  RegionID,

  STUFF(

       (

         SELECT ',' + T.c1

         FROM #tmp T

         WHERE A.regionid = T.regionid

         FOR XML PATH('')

       ), 1, 1, ''

     ) as group_concat

FROM #tmp A

Group by  RegionID

利用STUFF函数,去掉了第一个逗号,完成了最终sql语句。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/mysqltop/article/details/124252173
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计