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

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

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. 使用闭包和lambda解决问题与常规方式解决问题的对比。

    先来描述一下问题吧,游戏中的物品原来只有一个属性加成:攻击,防御,获得经验加成,金币加成,等等.现在要增加一个属性,这个属性可以为之前的属性之一. 这个属性加成涉及到类里的三个属性,value,typ ...

  2. 《Cracking the Coding Interview》——第1章:数组和字符串——题目6

    2014-03-18 01:45 题目:给定一个NxN的矩阵,就地旋转90度.(没有样例又不说方向的话,随便往哪儿转.) 解法:如果N为奇数,除了中心点以外四等分.如果N为偶数,四等分.按照A-> ...

  3. h5布局之道(最终篇)

    大家好,时隔一年多了,前几篇探讨的rem布局后来又有改进不过一直没有想起来更新博客,rem布局淘宝用的也比较早,有兴趣的可以看看淘宝的flexible ,我的用法比较简单,原来一样,废话不说了直接上代 ...

  4. 孤荷凌寒自学python第七天 列表的复制与序列的基本运算

    孤荷凌寒自学python第七天 列表的复制与序列的基本运算 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) (同步语音:https://www.ximalaya.com/keji/191030 ...

  5. ironic如何支持部署时按需RAID?

    新浪大神推荐使用element proliant-tools制作deploy image.element proliant-tools会在ipa ramdisk中安装一个rpm包hpssacli(HP ...

  6. springboot13 Hikari 和Introspector

    SpringBoot Initializr Introspector(内省) class TestReflect { @Test fun testReflect() { //获取字节码对象 val c ...

  7. 团队项目-第七次scrum 会议

    时间:11.3 时长:30分钟 地点:F楼1039教室 工作情况 团队成员 已完成任务 待完成任务 解小锐 学习cocos creator样例 修复员工招聘时bug 陈鑫 完成fire()与UI的对接 ...

  8. 四、vue派发更新

    收集的目的就是为了当我们修改数据的时候,可以对相关的依赖派发更新,那么这一节我们来详细分析这个过程. setter 部分的逻辑: /** * Define a reactive property on ...

  9. [NOWCODER] myh的超级多项式

    题面 已知$f_i=(\sum_{j=1}^ka_j{v_j}^i )\bmod 1004535809$ 给定$v_1,v_2,\ldots,v_k,f_1,f_2,\ldots f_k$ 求$f_n ...

  10. h5滚动条加载到底部

    https://www.zhihu.com/question/31861301 重复加载问题 http://www.jianshu.com/p/12aa901bee1f?from=timeline w ...