zoukankan      html  css  js  c++  java
  • SQL 列转行,即多行合并成一条

    需求:按照分组,将多条记录内容合并成一条,效果如下:

    数据库示例:

    复制代码
    CREATE TABLE [t2]([NID] [bigint] NULL,[district] [nvarchar](255) NULL,[town] [nvarchar](255) NULL);
    insert into t2 values(1,'淮上区','曹老集镇');
    insert into t2 values(2,'淮上区','淮滨街道');
    insert into t2 values(3,'淮上区','梅桥乡');
    insert into t2 values(4,'淮上区','吴小街镇');
    insert into t2 values(5,'淮上区','小蚌埠镇');
    insert into t2 values(1,'光明新区','公明街道');
    insert into t2 values(2,'光明新区','光明街道');
    insert into t2 values(1,'吉利区','大庆路街道');
    insert into t2 values(2,'吉利区','吉利乡');
    复制代码

    根据不同的SQL版本,可以有以下方法:

    一、SQL 2000 不支持FOR XML,不支持CONCAT。只能写自定义函数。

    复制代码
    CREATE FUNCTION dbo.townconcat(@district nvarchar(255)) 
    RETURNS varchar(8000) 
    AS 
    BEGIN 
        DECLARE @str varchar(8000) 
        SET @str = '' 
        SELECT @str = @str + ',' + town FROM t2 WHERE district=@district 
        RETURN STUFF(@str, 1, 1, '') 
    END 
    GO 
    -- 调用函数 
    SELECt district, town = dbo.townconcat(district) FROM t2 GROUP BY district 
    
    drop function dbo.townconcat
    go
    复制代码

    二、SQL 2012 支持 concat,2000版本自定义函数的基础上可少量优化

    --将2000版中的
    SELECT @str = @str + ',' + town FROM t2 WHERE district=@district
    --变成
    SELECT @str = concat(@str,',',town) FROM t2 WHERE district=@district 
    
    其他代码不变


    三、SQL2005支持for xml,可以大量简化

    select distinct a.district,
    (SELECT town+','FROM t2 where district=a.district FOR XML PATH(''))as towns 
    from t2 a

    以上三种方法都可以实现同样的效果。效果第一段的需求中的效果。

    四、分析:
    以上3种方法各有优劣,个人喜欢for xml的方式,因为够简单,一条select解决,可以直接适用于各视图中。

    核心的代码是:

    SELECT town+','FROM t2  FOR XML PATH('')

    上面的代码得到的结果为:

    注:
    1、上图中的列名是自动生成的,不可以通过as 来命名。
    2、我们不可以select多列,比如SELECT district,town+',' as tt FROM t2  FOR XML PATH('')。

    如果加上,并不会报错,但效果可能不是我们想要的,如下图:

    那我们如何根据关键字段来分组呢,我们可以把(select ..FOR XML..)作为子查询生成字段,看下图:

    得到上图就明白了吧,直接用distinct就可以了,见三。

  • 相关阅读:
    Spring+Hibernate集成后事务与Session的一些理解。
    对Spring的一些个人理解
    centos5.8 x86_64安装oracle10g
    C#中MessageBox用法大全(附效果图)
    解决SQL Server管理器无法连接远程数据库的问题
    【sql2000数据库】Named Pipes Provider error 40
    用SQL数据库批量插入数据简介
    DBGridEH在Delphi7中的安装方法及使用说明
    sql server中datetime字段只取年月日如20060421,默认值如何设置?getdate()得到的是包含时分秒的时间。
    获取 Windows 窗体 DataGridView 控件中选定的单元格、行和列
  • 原文地址:https://www.cnblogs.com/soundcode/p/6790651.html
Copyright © 2011-2022 走看看