zoukankan      html  css  js  c++  java
  • (4.28)for xml path 在合并拆分上的作用演示

    for xml path 用于合并与拆分

     

    1、合并

      很多时候需要在SQL Server中创建逗号分隔列表。这可以使用SQL Server的DOR XML PATH功能完成。

      与select语句一起使用时,FOR XML PATH生成一个xml。其示例如下所示。

    【1.1】基本演示

      上面的查询创建了一个表变量,并使用FOR XML PATH对其进行简单的选择。我们案例中的分隔符是“,”。上述查询的输出如下所示。

          1_create sql中的逗号分隔列表

      我们得到一个逗号分隔列表,但是我们仍然需要摆脱“a”之前的第一个逗号。这可以使用STUFF功能完成,如下所示。

      上面的查询删除了烦人的“,”并返回以下结果。

     

          2_在sql中创建逗号分隔列表

    【1.2】一个应用场景与FOR XML PATH应用

            首先呢!我们在增加一张学生表,列分别为(stuID,sName,hobby),stuID代表学生编号,sName代表学生姓名,hobby列存学生的爱好!那么现在表结构如下:

               

            这时,我们的要求是查询学生表,显示所有学生的爱好的结果集,代码如下:

    SELECT B.sName,LEFT(StuList,LEN(StuList)-1) as hobby FROM (
    SELECT sName,
    (SELECT hobby+',' FROM student 
      WHERE sName=A.sName 
      FOR XML PATH('')) AS StuList
    FROM student A 
    GROUP BY sName
    ) B 

             结果如下

     分析: 好的,那么我们来分析一下,首先看这句:

    SELECT hobby+',' FROM student 
      WHERE sName=A.sName 
      FOR XML PATH('')

    这句是通过FOR XML PATH 将某一姓名如张三的爱好,显示成格式为:“ 爱好1,爱好2,爱好3,”的格式!

    那么接着看:

    SELECT B.sName,LEFT(StuList,LEN(StuList)-1) as hobby FROM (
    SELECT sName,
    (SELECT hobby+',' FROM student 
      WHERE sName=A.sName 
      FOR XML PATH('')) AS StuList
    FROM student A 
    GROUP BY sName
    ) B  

      剩下的代码首先是将表分组,在执行FOR XML PATH 格式化,这时当还没有执行最外层的SELECT时查询出的结构为:

        

      可以看到StuList列里面的数据都会多出一个逗号,这时随外层的语句:SELECT B.sName,LEFT(StuList,LEN(StuList)-1) as hobby  就是来去掉逗号,并赋予有意义的列明!

    2、拆分

    【2.1】利用Xquery方式

      这是将列表转换为表的快速SQL函数。

    上述查询利用SQL Server的Xquery功能来分割分隔值。该功能可以如下所示使用

        sql函数将列表转换为表

    【2.2】利用split方式(推荐)

    --split函数
    --SELECT * FROM dbo.split('581::579::519::279::406::361::560',':')  
    ALTER Function [dbo].[Split](@Sql varchar(8000),@Splits varchar(10))  
    returns @temp Table (a varchar(100))  
    As  
    Begin  
      Declare @i Int  
      Set @Sql = RTrim(LTrim(@Sql))  
      Set @i = CharIndex(@Splits,@Sql)  
      While @i >= 1  
      Begin 
       Insert @temp Values(Left(@Sql,@i-1)) 
       Set @Sql = SubString(@Sql,@i+1,Len(@Sql)-@i) 
       Set @i = CharIndex(@Splits,@Sql) 
      End 
      If @Sql <> ''  
      Insert @temp Values (@Sql)  
      Return  
    End 

    案例演示

      【1】原始数据

        

      【2】运行之后获得的数据

        

    【2.3】直接使用T-SQL列转行(数据量小可用)

    列转行

    ----------------------------------------------------------------

    --> 测试数据[huang]
    if object_id('[huang]') is not null drop table [huang]
    go 
    create table [huang]([a] nvarchar(4),[b] nvarchar(10))
    insert [huang]
    select 'X1','1,4,8' union all
    select 'X2','2' union all
    select 'X3','3,6' union all
    select 'X4','7' union all
    select 'X5','5'
     
    解决问题代码语句:
    select 
        a.[a], 
        SUBSTRING(a.[b],number,CHARINDEX(',',[b]+',',b.number)-b.number) as [b] ,
        b.number
    from
        [huang] a,master..spt_values b
    where
        b.number >=1 and b.number<=len(a.[b])  
        and b.type='p' 
        and substring(','+a.[b],b.number,1)=','
    
    --演示代码
    select * from master..spt_values 
    where type='p' 
    order by number
    ----------------结果----------------------------
     
  • 相关阅读:
    流程控制
    小结
    运算符
    进制之间的转换
    自动类型转换和强制类型转换
    变量
    关键字,标识符,
    NGINX 做TCP转发(端口转发)并记录日志
    redash安装
    解决 es CircuitBreakingException 问题(Data too large Error)
  • 原文地址:https://www.cnblogs.com/gered/p/10650510.html
Copyright © 2011-2022 走看看