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配 ...
随机推荐
- hadoop中namenode启动失败
jps发现namenode启动失败 每次开机都要重新格式化一下namenode才可以 其实问题出现自tmp文件上,因为每次开机就会被清空,所以现在我们配置一个tmp文件目录. 如果之前没有配置过,默认 ...
- VSX-2 搭建项目
由于是公司的项目,也不可能直接拿过来写博客,所以准备搭建一个自己的VSX项目. 项目需求这里就不写了,大体可参考曾经的一篇文章,这个VSX项目就是用来简化插件式开发. 本文开始正式记录做这个VSX项目 ...
- 新生 & 语不惊人死不休 —— 《无限恐怖》读后有感
开篇声明,我博客中“小心情”这一系列,全都是日记啊随笔啊什么乱七八糟的.如果一不小心点进来了,不妨直接关掉.我自己曾经写过一段时间的日记,常常翻看,毫无疑问我的文笔是很差的,而且心情也是瞬息万变的.因 ...
- 1020 Tree Traversals (25 分)(二叉树的遍历)
给出一个棵二叉树的后序遍历和中序遍历,求二叉树的层序遍历 #include<bits/stdc++.h> using namespace std; ; int in[N]; int pos ...
- 团队项目-第一次Scrum 会议
时间:10.23 时长:30分钟 地点:F楼2层沙发休息处 工作情况 团队成员 已完成任务 待完成任务 解小锐 学习使用cocos creator 学习官方样例 陈鑫 学习JavaScript 学习c ...
- 201621123034 《Java程序设计》第11周学习总结
作业11-多线程 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread ...
- POJ 2983-Is the Information Reliable
Description The galaxy war between the Empire Draco and the Commonwealth of Zibu broke out 3 years a ...
- MPS添加管理设备实例NS的过程
MPS添加管理设备实例NS的过程 MPS添加实例NS设备节点: > show snmp community Done > > add snmp community public al ...
- background-size属性的几个实用的值
先来看w3c的background-size的几个值: background-size:cover; 把背景图像扩展至足够大,以使背景图像完全覆盖背景区域.背景图像的某些部分也许无法显示在背景定 ...
- CF992E Nastya and King-Shamans 解题报告
CF992E Nastya and King-Shamans 题意翻译 给定一个序列 \(a_i\),记其前缀和序列为 \(s_i\),有 \(q\) 个询问,每次单点修改,询问是否存在一个 \(i\ ...