在项目开发中,有时会碰到将列记录合并为一行的情况,例如根据地区将人员姓名合并,或根据拼音首字母合并城市等,下面就以根据地区将人员姓名合并为例,详细讲一下合并的方法。

首先,先建一个表,并添加一些数据,建表代码如下:

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 @NC

END
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—列记录合并成一行的更多相关文章

  1. MSSQL-字符串分离与列记录合并成一行混合使用

    一般我们在数据库的表字段存储字典Id,如果有多个的话一般是用,或分隔符分隔(12,14),列表显示的时候是显示字典名,那如果要在数据库将字典Id转成用户看得懂的字典名,该怎么办呢? 我们这时候可以结合 ...

  2. MSSQL—列记录合并

    在项目开发中,有时会碰到将列记录合并为一行的情况,例如根据地区将人员姓名合并,或根据拼音首字母合并城市等,下面就以根据地区将人员姓名合并为例,详细讲一下合并的方法. 首先,先建一个表,并添加一些数据, ...

  3. MSSQL列记录合并

    创建表及插入数据 If OBJECT_ID(N'Demo') Is Not Null Begin Drop Table Demo End Else Begin Create Table Demo( A ...

  4. ORACLE 多列合并成一行数据 WM_CONCAT函数以及REPLACE

    WM_CONCAT()方法 注意字符长度 SELECT BERTHCODE,tpf.freedatetype, ( SELECT WM_CONCAT(SBPT.PARKSTIME||'~'||SBPT ...

  5. mysql去重, 把url重复且区为空的中去掉、统计重复数据、、结果集去重合并成一行

    delete from 表名 where id not in (select d.id from (SELECT id FROM 表名 GROUP BY c1,c2,c3,c4)as d) #去重复, ...

  6. SQL将多行数据合并成一行【转】

    转:https://blog.csdn.net/AntherFantacy/article/details/83824182 今天同事问了一个需求,就是将多行数据合并成一行进行显示,查询了一些资料,照 ...

  7. 将txt多行文本合并成一行

    1.用word打开txt文本2.打开“替换”功能,查找内容“^p”,替换内容为“,”(均无双引号).即可把多列文字合并为一行.

  8. 使用Notepad++将多行数据合并成一行

    1.按Ctrl+F,弹出“替换”的窗口: 2.选择“替换”菜单: 3.“查找目标”内容输入为:\r\n: 4.“替换为”内容为空: 5.“查找模式”选择为正则表达式: 6.设置好之后,点击“全部替换” ...

  9. ELK之使用filebeat的多行过滤插件把多行合并成一行

    java运行日志一般有多行,格式类似如下 格式为:日期 + 日志级别 + 日志信息 有些日志是多行的,需要使用filebeat多行插件把多行合并成一行 未使用多行插件的日志格式 修改filebeat配 ...

随机推荐

  1. TerminateProcess

    Remarks The TerminateProcess function is used to unconditionally cause a process to exit. The state ...

  2. Oracle 11g数据库安装与卸载的方法图解(windows)

    一.Oracle 11g安装 安装之前要先确定自己的电脑配置,以windows为例,如果是win7以下系统如xp等,可以选择Oracle 10g.因为10g的程序文件只有200多兆,而11g及达到了2 ...

  3. hash算法和常见的hash函数 [转]

       Hash,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值. 这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能 会散列成相同的输出,而不 ...

  4. Vbs 测试程序三

    一段被写滥了的VBS代码 值得一提的是感兴趣的同学可以把 chr(13) + chr(13) + chr(13) 改为chr(11) + chr(11) + chr(11) 不赘述 on error ...

  5. 【Lowest Common Ancestor of a Binary Tree】cpp

    题目: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. Accor ...

  6. 【转载】总结使用Unity3D优化游戏运行性能的经验

    流畅的游戏玩法来自流畅的帧率,而我们即将推出的动作平台游戏<Shadow Blade>已经将在标准iPhone和iPad设备上实现每秒60帧视为一个重要目标. 以下是我们在紧凑的优化过程中 ...

  7. 动态删边SPFA: [HNOI2014]道路堵塞

    [HNOI2014]道路堵塞 题目描述 $A$ 国有 $N$座城市,依次标为$1$到$N$.同时,在这$N$座城市间有$M$条单向道路,每条道路的长度是一个正整数.现在,$A$国交通部指定了一条从城市 ...

  8. NodeJs02 美女爬虫

    note: demo代码要编号 导出模块 一个js文件就是一个模块,模块内部的所有变量,对象,方法对外界都不可见.如果想暴漏出去让别人用,就需要导出模块.语法如下: module.exports = ...

  9. 使用SecureCRT设置linux系统登录的ssh公钥认证

    1.修改ssh配置文件/etc/ssh/sshd_configRSAAuthentication yes                             //使用RSA加密算法PubkeyAu ...

  10. Dev express 笔记

    1.设置treelist不同行的颜色 void treeList1_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDr ...