当前位置:网站首页>SQL Server实现group_concat功能
SQL Server实现group_concat功能
2022-08-02 19:24:00 【m0_67401382】
一、实现
#tmp表内容如下:
实现group_concat的sql语句为:
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、FORXMLPATH的作用
FORXMLPATH的作用是将查询结果集以XML形式展现,将多行的结果,展示在同一行,例如:
select?c1?from?#tmp?where?RegionID?=?41653
其结果集如下:
select?c1?from?#tmp?where?RegionID?=?41653?FOR?XML?PATH('')
当sql语句加上FORXMLPATH(‘’)后,其结果集输出是:
具体输出的字符如下:
30.32680930.32798230.34793330.38810430.39283030.36793130.36805230.36784230.35731830.35734930.357349
通过字符拼接后可以把xml信息清除,并以指定的字符进行分割:
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函数的作用是将字符串插入到另一个字符串中。它从第一个字符串的开始位置删除指定长度的字符,然后将第二个字符串插入到第一个字符串的开始位置。其语法为:
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、一个简单的groupby
Select RegionID?
FROM?#tmp?A
Group?by?RegionID
这个sql各位看官都十分熟悉,已经没什么好说的了。
2.3.2、在select语句后面加上子查询
Select RegionID,
(
SELECT?','?+?T.c1
FROM?#tmp?T
WHERE?A.regionid?=?T.regionid
FOR?XML?PATH('')
)?
FROM?#tmp?A
Group?by?RegionID
在上述简单的groupby语句基础上加入一个select里的子查询,其结果如下:
在该子查询中,当外层的groupby返回结果集中的第一行RegionID为41653时,这个值被子查询的where条件所使用,相当于:
SELECT?','?+?T.c1
FROM?#tmp?T
WHERE?T.regionid?=?41653
FOR?XML?PATH('')
因为FORXMLPATH把多行记录打平成一条记录,因此此时的返回结果为:
接着第groupby返回结果集中的第二行45761传入该子查询,依次类似上面描述的执行,直到所有外层的值遍历完成。
2.3.3、去掉子查询结果集的第一个分隔符
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语句。
长按下图二维码,关注更多数据库实用技巧。
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
猜你喜欢
TPAMI2022 | TransCL:基于Transformer的压缩学习,更灵活更强大
Brain-computer interface 003 | Musk said that he has realized a virtual self-dialogue with the cloud, and related concept shares have risen sharply
Therapy | How to Identify and Deal with Negative Thoughts
Electron使用指南之初体验
Fetch 请求不转换BLOB正常显示GBK编码的数据
磁盘分区的知识
Geoserver + mysql + openlayers problem
程序员也许都缺一个“二舅”精神
Unity 打包和切换平台|Build Settings窗口介绍
MySQL安装时一直卡在starting server
随机推荐
Caldera(一)配置完成的虚拟机镜像及admin身份简单使用
Silver circ: letter with material life insurance products should be by the insurance company is responsible for the management
MaxCompute 的SQL 引擎参数化视图具体有哪些增强功能?
In action: 10 ways to implement delayed tasks, with code!
idea 配置resin
Office2021 安装MathType
牛客题目——滑动窗口的最大值、矩阵最长递增路径、顺时针旋转矩阵、接雨水问题
image could not be accessed on a registry to record its digest
golang面试题
LeetCode:622. 设计循环队列【模拟循环队列】
看完这篇,轻松get限流!
我用这一招让团队的开发效率提升了 100%!
el-tree渲染大量数据的解决方案(不通过懒加载)
MySQL 事件调度
7.22 - 每日一题 - 408
golang刷leetcode 经典(12) 完全二叉树插入器
leetcode刷题记录:7.整数反转,8.字符串转整数,9.回文数
The so-called fighting skill again gao also afraid of the chopper - partition, depots, table, and the merits of the distributed
J9数字论:互联网跨链桥有什么作用呢?
移动跨端技术方案分析对比