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

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

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. SQL多表合并查询结果

    两表合并查询,并同时展示及分页SELECT a.* FROM ( ( SELECT punycode, `domain`, 'Success' AS state, add_time, AS refun ...

  2. oracle中的连接查询与合并查询总结

    连接查询: 连接查询是指基于多张表或视图的查询.使用连接查询时,应指定有效的查询条件,不然可能会导致生成笛卡尔积.如现有部门表dept,员工表emp,以下查询因查询条件无效,而产生笛卡尔积:   (各 ...

  3. 7-11使用UNION合并查询

    合并查询的语法: SELECT ...FROM  表名一 UNION SELECT ...FROM 表名二 合并查询的特点: 1: 合并表中的列的个数,数据类型数据类型相同或兼容. 2:UNION 默 ...

  4. SQL SERVER连接、合并查询

    ----创建测试表MyStudentInfoCREATE table MyStudentInfo(  Id int not null primary key,  Name varchar(16),  ...

  5. oracle 基础SQL语句 多表查询 子查询 分页查询 合并查询 分组查询 group by having order by

    select语句学习 . 创建表 create table user(user varchar2(20), id int); . 查看执行某条命令花费的时间 set timing on: . 查看表的 ...

  6. Oracle 表复杂查询之多表合并查询

    转自:https://www.cnblogs.com/GreenLeaves/p/6635887.html 本文使用到的是oracle数据库scott方案所带的表,scott是oracle数据库自带的 ...

  7. sql 内连接 子查询 合并查询

    -- 内连接:-- 显示员工姓名.工资和公司所在地 select e.ename, e.sal, d.dname from emp e,dept d; -- 笛卡尔积 select e.ename, ...

  8. oracle的多表合并查询-工作心得

    本随笔文章,由个人博客(鸟不拉屎)转移至博客园 发布时间: 2018 年 11 月 29 日 原地址:https://niaobulashi.com/archives/oracle-select-al ...

  9. 使用union合并查询

    语法: select …..from 表1 union select ……from 表2 2. 合并查询的特点 ① 合并的表中的列的个数.数据类型必须相同或向兼容. ② union默认去掉重复值,如果 ...

随机推荐

  1. 2019南昌邀请赛 L 计算几何 G(待补)

    #include<bits/stdc++.h> const double PI=acos(-1.0); ; using namespace std; struct Point { doub ...

  2. 自己用的Xshell配色方案

    [comfort]text=dce2e2cyan(bold)=2ad1b8text(bold)=dce2e2magenta=dd3682green=55bb55green(bold)=55bb55ba ...

  3. axios delete

  4. day02 python数据类型

    python里面常见的数据类型 目录 一.int 整形只有一个方法bit_length() 可以显示二进制长度 a = 10b = a.bit_length()print(b)1010 二.bool ...

  5. 西门子S7-300 PLC视频教程(百度网盘)

    西门子S7-300 PLC视频教程(百度网盘) 百度网盘链接地址: 链接:https://pan.baidu.com/s/1MqC0DJbv-ndCzk9XGU2AYQ 提取码:u5eq 祝大家天天开 ...

  6. Ansible 之动态Inventory文件(二)

    上篇主要讲解了Ansible 的安装和配置,并且根据不同的业务场景将服务器的信息存放在Ansible的Inventory中,其实存放这样的数据每次更新都需要我们自动的添加和删除,这样对于我们维护起来很 ...

  7. Windows Server 2008 R2 /2012 修改密码策略

    今天建了域环境,在添加新用户的时候,发现用简单的密码时域安全策略提示密码复杂度不够,于是我就想在域安全策略里面把密码复杂度降低一点. 问题:    在“管理工具 >> 本地安全策略 > ...

  8. 动态调用WebService的代理类

    using System; using System.Collections; using System.ComponentModel; using System.Data; using System ...

  9. Linux操作汇总

    添加环境变量 CMD,或添加到/etc/profile,或添加到各自账户下的~/.profile.(后两种需要重新source) export PATH=/home/alan/Desktop/arm- ...

  10. InfluxDB安装和简介

    InfluxDB是一个当下比较流行的时序数据库,InfluxDB使用 Go 语言编写,无需外部依赖,安装配置非常方便,适合构建大型分布式系统的监控系统. 一.InfluxDB 简介 InfluxDB ...