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

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

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

MSSQL—列记录合并的更多相关文章

  1. MSSQL—列记录合并成一行

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

  2. MSSQL列记录合并

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

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

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

  4. Oracle多行记录合并的几种方法

    今天正好遇到需要做这个功能,顺手搜了一下网络,把几种方法都列出来,方便以后参考. 1 什么是合并多行字符串(连接字符串)呢,例如: SQL> desc test; Name Type Nulla ...

  5. Spark DataFrame列的合并与拆分

    版本说明:Spark-2.3.0 使用Spark SQL在对数据进行处理的过程中,可能会遇到对一列数据拆分为多列,或者把多列数据合并为一列.这里记录一下目前想到的对DataFrame列数据进行合并和拆 ...

  6. Repeater多列分别合并单元格

    GridView.Repeater合并单元格可以参考http://www.cnblogs.com/zhmore/archive/2009/04/22/1440979.html,但是原文例子是合并一列的 ...

  7. DataGrid列的合并

    /// <summary> /// DataGrid列的合并 /// 注意:1.DataGrid在绑定的时候进行分组和排序,才能让相同的行放在一起 /// 2.方法应用的时机,应该在Dat ...

  8. Linux:不同文件相同列字符合并文件(awk函数)

    存在file1.txt,其内容如下: H aa 0 0 1 -9 H bb 0 0 2 -9 H cc 0 0 2 -9 存在file2.txt,其内容如下: H aa 0 0 0 -9 asd qw ...

  9. Oracle多行记录合并自定义函数

    在oracle数据库中,进行字段合并,可以使用wm_concat(column)函数,但是在这种方法不被Oracle所推荐,因为WMSYS用户用于Workspace Manager,其函数对象可能因版 ...

随机推荐

  1. myhandle

    #ifndef my_handle_h #define my_handle_h #include <stdint.h> #include "mydef.h" #incl ...

  2. python爬取数据保存入库

    import urllib2 import re import MySQLdb class LatestTest: #初始化 def __init__(self): self.url="ht ...

  3. 安装 node-sass 的正确姿势

    SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ npm install node-sass

  4. daydayup2 codeforces143D

    这题很考察分析 题意:让你构造n*m的矩阵,使得不存在两个点的距离的平方为5 1若n=1  ,答案为m 2若m=1,答案为n 3若n=2 则这样 110011001100.. 110011001100 ...

  5. android studio 导入一个已有的android studio project作为lib使用

    android studio 导入一个已有的android studio project作为lib使用 新项目来了. 需要搭建框架. android studio对我来说还是很陌生,之前一个项目在同事 ...

  6. (转)客户端触发Asp.net中服务端控件事件

    第一章. Asp.net中服务端控件事件是如何触发的 Asp.net 中在客户端触发服务端事件分为两种情况: 一. WebControls中的Button 和HtmlControls中的Type为su ...

  7. wx jssdk

    public static Dictionary<string,string> jsstr(string url) { //noncestr ); //timestamp TimeSpan ...

  8. MySQL workbench 中文乱码 显示口口

    Edit-->perference...-->Apperance  如下图 即可 转载自:http://blog.csdn.net/shxluwei/article/details/802 ...

  9. Visual Studio 2015 Update 3 ISO

    http://download.microsoft.com/download/c/2/6/c26892d8-6a5d-4871-9d46-629f4d430146/vs2015.3.vsu.iso

  10. 使用命令行工具运行Xcode 7 UI Tests

    原文:Run Xcode 7 UI Tests from the command line 苹果在Xcode 7中引入了一项新技术UI Tests,允许开发者使用Swift或Objective C代码 ...