MSSQL—列记录合并成一行
在项目开发中,有时会碰到将列记录合并为一行的情况,例如根据地区将人员姓名合并,或根据拼音首字母合并城市等,下面就以根据地区将人员姓名合并为例,详细讲一下合并的方法。
首先,先建一个表,并添加一些数据,建表代码如下:
If OBJECT_ID(N'Demo') Is Not Null
Begin
Drop Table Demo
End
Else
Begin
Create Table Demo(
Area nvarchar(30),
Name nvarchar(20))Insert Into Demo(Area,Name)
Values(N'北京',N'张三'),
(N'上海',N'李四'),
(N'深圳',N'王五'),
(N'深圳',N'钱六'),
(N'北京',N'赵七'),
(N'北京','Tom'),
(N'上海','Amy'),
(N'北京','Joe'),
(N'深圳','Leo')
End
Go
建完后查询一下,可见表中数据如下:

如果仅将Name列合并,不遵循任何条件的话,我们可以采用两种方法,第一种就是采用FOR XML PATH方式,代码如下:
SELECT ','+Name FROM dbo.Demo FOR XML PATH('')
运行结果如下:

关于FOR XML PATH的详细介绍可参考MSDN:搭配 FOR XML 使用 PATH 模式
第二种方法就是定义一个变量用来装载查询的结果,代码如下:
Declare @NameCollection nvarchar(500)
Select @NameCollection=ISNULL(@NameCollection+',','')+Name From dbo.Demo
Select @NameCollection as NameCollection
运行结果如下:

加了ISNULL是因为最开始变量@NameCollection为NULL,为了避免“张三”前多一个逗号(“,”)而采用的替换。
上面讲了在无条件的情况下合并一列,但是在项目中几乎不会遇到这样的情况,一般都是根据某一列来合并另一列的数据,例如我们现在要根据Area将Name合并,得到这样的结果:

有了上面的基础,要合并成这样的数据就容易了,我们只需要针对Area列采用聚合GROUP BY或取不重复值DISTINCT,然后根据Area列合并Name列,有了思路,下面就来说说如何实现,首先还是采用FOR XML PATH方式,结合自连接,首先先按Area列对Name列进行合并,代码如下:
SELECT Area,
(SELECT ','+Name FROM dbo.Demo WHERE Area = t.Area FOR XML PATH(''))
AS NameCollection FROM dbo.Demo AS t
运行结果如下:

现在有两点还没实现,第一是结果重复了,第二是NameCollection列最开始都多了一个逗号,先去掉逗号,采用STUFF 函数来进行替换,代码修改如下:
SELECT Area,
STUFF((SELECT ','+Name FROM dbo.Demo WHERE Area = t.Area FOR XML PATH('')),1,1,'')
AS NameCollection FROM dbo.Demo AS t
现在运行后结果如下:

下面就剩下去掉重复数据了,分别采用GROUP BY和DISTINCT,代码如下:
SELECT DISTINCT Area,
STUFF((SELECT ','+Name FROM dbo.Demo WHERE Area = t.Area FOR XML PATH('')),1,1,'')
AS NameCollection FROM dbo.Demo AS t
SELECT Area,
STUFF((SELECT ','+Name FROM dbo.Demo WHERE Area = t.Area FOR XML PATH('')),1,1,'')
AS NameCollection FROM dbo.Demo AS t GROUP BY Area
关于STUFF函数可以参考MSDN介绍:STUFF函数
运行结果即为最终我们需要的结果,最开始在上面讲到了一种用变量来装载查询结果实现合并一列的方法,下面详细介绍如何采用上述方法来实现我们的需求,我们可以根据上面的方法建一个函数,传入一个Area参数,根据Area来进行合并,返回合并值,函数如下:
CREATE FUNCTION MergeByColumn
(
-- Add the parameters for the function here
@Area nvarchar(30)
)
RETURNS nvarchar(500)
AS
BEGIN
-- Declare the return variable here
DECLARE @NC nvarchar(500)-- Add the T-SQL statements to compute the return value here
SELECT @NC=ISNULL(@NC+',','')+Name FROM dbo.Demo WHERE Area=@Area-- Return the result of the function
RETURN @NCEND
GO
建好后测试下,以传入参数为“北京”为例,运行如下代码:
SELECT dbo.MergeByColumn('北京') AS NameCollection
得到结果如下:

现在只需将Area列也加入查询即可,修改代码如下:
SELECT Area,dbo.MergeByColumn(Area) AS NameCollection From dbo.Demo
现在也得到了重复的结果,如下:

去重复同样可以用GROUP BY和DISTINCT,代码如下,即可以得到我们最终的结果:
SELECT DISTINCT Area,dbo.MergeByColumn(Area) AS NameCollection From dbo.Demo
SELECT Area,dbo.MergeByColumn(Area) AS NameCollection From dbo.Demo GROUP BY Area
本文转自:http://www.cnblogs.com/leolis/p/3977569.html
MSSQL—列记录合并成一行的更多相关文章
- MSSQL-字符串分离与列记录合并成一行混合使用
一般我们在数据库的表字段存储字典Id,如果有多个的话一般是用,或分隔符分隔(12,14),列表显示的时候是显示字典名,那如果要在数据库将字典Id转成用户看得懂的字典名,该怎么办呢? 我们这时候可以结合 ...
- MSSQL—列记录合并
在项目开发中,有时会碰到将列记录合并为一行的情况,例如根据地区将人员姓名合并,或根据拼音首字母合并城市等,下面就以根据地区将人员姓名合并为例,详细讲一下合并的方法. 首先,先建一个表,并添加一些数据, ...
- MSSQL列记录合并
创建表及插入数据 If OBJECT_ID(N'Demo') Is Not Null Begin Drop Table Demo End Else Begin Create Table Demo( A ...
- ORACLE 多列合并成一行数据 WM_CONCAT函数以及REPLACE
WM_CONCAT()方法 注意字符长度 SELECT BERTHCODE,tpf.freedatetype, ( SELECT WM_CONCAT(SBPT.PARKSTIME||'~'||SBPT ...
- mysql去重, 把url重复且区为空的中去掉、统计重复数据、、结果集去重合并成一行
delete from 表名 where id not in (select d.id from (SELECT id FROM 表名 GROUP BY c1,c2,c3,c4)as d) #去重复, ...
- SQL将多行数据合并成一行【转】
转:https://blog.csdn.net/AntherFantacy/article/details/83824182 今天同事问了一个需求,就是将多行数据合并成一行进行显示,查询了一些资料,照 ...
- 将txt多行文本合并成一行
1.用word打开txt文本2.打开“替换”功能,查找内容“^p”,替换内容为“,”(均无双引号).即可把多列文字合并为一行.
- 使用Notepad++将多行数据合并成一行
1.按Ctrl+F,弹出“替换”的窗口: 2.选择“替换”菜单: 3.“查找目标”内容输入为:\r\n: 4.“替换为”内容为空: 5.“查找模式”选择为正则表达式: 6.设置好之后,点击“全部替换” ...
- ELK之使用filebeat的多行过滤插件把多行合并成一行
java运行日志一般有多行,格式类似如下 格式为:日期 + 日志级别 + 日志信息 有些日志是多行的,需要使用filebeat多行插件把多行合并成一行 未使用多行插件的日志格式 修改filebeat配 ...
随机推荐
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目3
2014-04-23 18:10 题目:设计一个点唱机. 解法:英文叫Musical Jukebox.这是点唱机么?卡拉OK么?这种题目实在是云里雾里,又没有交流的余地,我索性用一个vector来表示 ...
- nosetests
1.nosetests 执行出测试报告 提前安装 插件nose-html系列插件 nosetests -v --with-html-output --html-out-file=报告名.html ...
- Python学习-前台开发-JavaScript、Dom和jQuery
JavaScript JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. ...
- LDA和PCA降维的原理和区别
LDA算法的主要优点有: 在降维过程中可以使用类别的先验知识经验,而像PCA这样的无监督学习则无法使用类别先验知识. LDA在样本分类信息依赖均值而不是方差的时候,比PCA之类的算法较优. LDA算 ...
- linux fork()函数 转载~~~~
转自 :: http://blog.csdn.net/jason314/article/details/5640969 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork ...
- table不让td中文字溢出操作方法
table不让td中文字溢出操作方法 table{ width:100px; table-layout:fixed;/* 只有定义了表格的布局算法为fixed,下面td的定义才能起作用. */ } t ...
- redis单线程问题
1.redis的单线程指的是什么单线程?同一个时间点只处理一个客户端的连接,也就是redis网络模块的单线程. 2.redis为什么设计成单线程 具体作者怎么想的,我不知道,我说一下我的理解(1)re ...
- Dubbo基础介绍
基础知识 Dubbo是什么:Dubbo是一个分布式的服务框架,提供高性能和透明化的RPC远程调用方案,以及SOA服务治理方案 Dubbo涉及的知识: 远程调用:RMI.hassion.webservi ...
- Linux命令 -磁盘和文件系统类
声明:本文所涉及到的Linux命令均为最常见的用法,未列举之参数,自行查阅man 1.df 磁盘容量 -h 以人类易读方式展示(GB.KB)等 df -h /usr 2.du 文件或目录的容量 -s ...
- Zigzag数组 -- 面试宝典
最近在看面试宝典,其中看到一个题目说:输入一个正整数n,输出它的zigzag数组. 分析:书上给出了数学方面的思考然后给了代码.但是我感觉如果真是面试或者考试遇到的话,我这种笨脑袋肯定是想不出来的,因 ...