首页 > 数据库 >SQL Server实现group_concat功能的详细实例

SQL Server实现group_concat功能的详细实例

时间:2023-04-25 23:23:32浏览次数:42  
标签:tmp XML group RegionID Server STUFF SQL PATH

目录

一、实现

#tmp表内容如下:

SQL Server实现group_concat功能的详细实例

实现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

实现效果如下:

SQL Server实现group_concat功能的详细实例

二、原理分析

2.1、FOR XML PATH的作用

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

1 select c1 from #tmp where RegionID = 41653

其结果集如下:

SQL Server实现group_concat功能的详细实例

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

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

SQL Server实现group_concat功能的详细实例

具体输出的字符如下:

30.32680930.32798230.34793330.38810430.39283030.36793130.36805230.36784230.35731830.35734930.357349

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

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

SQL Server实现group_concat功能的详细实例

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

2.2、STUFF函数

2.2.1、STUFF函数在本SQL的作用

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

SQL Server实现group_concat功能的详细实例

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

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

SQL Server实现group_concat功能的详细实例

需要详细了解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里的子查询,其结果如下:

SQL Server实现group_concat功能的详细实例

在该子查询中,当外层的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把多行记录打平成一条记录,因此此时的返回结果为:

SQL Server实现group_concat功能的详细实例

接着第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语句。

标签:tmp,XML,group,RegionID,Server,STUFF,SQL,PATH
From: https://www.cnblogs.com/lingdanglfw/p/17354333.html

相关文章

  • 监控自建MySQL慢查询日志并上报到企业微信集群
    shell脚本如下#!/bin/bash#设置企业微信机器人webhook地址和机器人名称WEBHOOK_URL="你的WEBHOOK_URL"BOT_NAME="MySQLSlowLogBot"#设置慢日志文件路径和记录已发送行数的文件路径LOG_FILE="/data/mysql/mysql-slow-log.log"SENT_LINE_FILE="/tmp/mysql-slow-log.sent......
  • java stream 多重groupingBy
    importcom.alibaba.fastjson.JSON;importlombok.Data;importjava.util.ArrayList;importjava.util.List;importjava.util.Map;importjava.util.stream.Collectors;/***@ClassNameTest*@Description*@Authorcsg*@Data2023/4/2521:31*@Version......
  • Geoserver使用rest接口发布图层
    Geoserver提供一系列rest接口,发布图层也可以通过rest接口进行图层发布接口post请求/rest/workspaces/{workspaceName}/datastores/{storeName}/featuretypes请求参数(主要参数)参数类型描述必填workspaceNamestring工作空间truestoreNamestring储存仓库t......
  • mysql基础 -- 单表练习
    droptableifexistsemp;createtableemp(empnoint,enamevarchar(50),jobvarchar(50),mgrint,hiredatedate,saldecimal(7,2),commdecimal(7,2),deptnoint)engine=innodbdefaultcharset=utf8;INSERTINTOempVALUES(7369,'SMITH','CL......
  • 【Azure 应用服务】启用 Managed Identity 登录 SQL Server 报错 Managed Identity au
    问题描述在AppService中启用Identity后,使用系统自动生成Identity。使用如下代码连接数据库SQLServer:SQLServerDataSourcedataSource=newSQLServerDataSource();dataSource.setServerName("yoursqlservername.database.chinacloudapi.cn");//Replacewit......
  • 【IT老齐014】阿里Canal实现MySQL异构数据同步
    【IT老齐014】阿里Canal实现MySQL异构数据同步场景商户在后台系统添加数据,消费者需要在前台获取数据。这时候需要将后台的数据同步到es中。mysql的数据跟es存储的数据不一样,称为异构数据。原始做法:团队A在java代码中新增mysql数据时,调用团队B的接口新增es商品数据。缺点:协......
  • 2.mysql binlog的三种格式及区别
    好文:https://www.cnblogs.com/syw20170419/p/16443105.html 1、三种格式:row、statement、mixed2、区别:row格式文件比较大,statement比较小,row格式保存的是一行一行的数据,statement保存的是sql语句,mixed格式介于二者之间,statement容易丢数据,row格式则不会3、statement容易丢......
  • SQL注入--数据外带(总结)
    目录导航  0x00数据外带平台  0x01DNS外带    MYSQL数据外带    MSSQL数据外带    Oracle数据外带    命令外带  0x02HTTP外带    MSSQL数据外带    Oracle数据外带0x00数据外带平台平台网址平台简介http......
  • sql同时删除多张表的数据/sql查询百分比
    https://blog.csdn.net/qq_32793985/article/details/114651944DELETE a, b, c FROM Aa LEFTJOINBbONa.bId=b.id LEFTJOINCcONa.cId=c.id WHERE --需要删除数据 a.id='666' --可以设置a/b/c表的限制条件 ANDb.type='1' ANDc.type......
  • PGSQL 查询哪些表要索引,查表行数
    转自:(96条消息)PostgreSQLindexmonitor——监控哪些表需要创建索引_foucus、的博客-CSDN博客在数据库的使用过程中,可能某些表随着数据量的增大而因为没有索引仍旧使用的全表扫描,我们可以使用下列脚本来监控哪些大表上需要创建索引。1、监控哪些表需要创建索引SELECTr......