zoukankan      html  css  js  c++  java
  • 很有意思的SQL多行数据拼接

    今天为了实现一个很原始的问题上网查资料,见到一个很有意思的SQL语句,和大家分享一下

    要实现的SQL查询很原始:

    要求从第一个表进行查询得到第二个表格式的数据,上网查询之后竟然能写出下面的SQL:

    复制代码代码如下:

    select * from userino 

    SELECT * FROM( 
    SELECT DISTINCT userpart 
    FROM userino 
    )A 
    OUTER APPLY( 
    SELECT 
    [usernames]= replace(replace(replace((SELECT username as value FROM userino N 
    WHERE userpart = A.userpart order by n.username asc FOR XML AUTO),'"/><N value="','/') 
    ,'<N value="',''),'"/>','') 
    )N 
    OUTER APPLY( 
    SELECT 
    [username_cns]= replace(replace(replace((SELECT username_cn as value FROM userino M 
    WHERE userpart = A.userpart order by m.username asc FOR XML AUTO),'"/><M value="','/') 
    ,'<M value="',''),'"/>','') 

    )M 

    现将SQL进行一下分析: 

    总共使用到的点有:OUTER APPLY,FOR XML AUTO。由于对SQL Server没有很深的研究,所以记录一下 

    OUTER APPLY 是SQL2005开始支持的一种查询方法,类似于连接查询,是将两个查询结果进行拼接,但是奇特的是,使用OUTER APPLY竟然能够在Apply后面的查询中使用前面已经得到的查询结果。 

    如: 
    复制代码代码如下:

    select * from 
    (select * from userino) A 
    cross join (select username from userino 
    where username = A.username )B 

    select * from 
    (select * from userino) A 
    join (select username from userino ) B on a.username = b.username 

    select * from 
    (select * from userino) A 
    OUTER APPLY (select username from userino 
    where username = A.username ) B 

    第一段SQL显然是错的,有两个原因:1.Cross Join本来就是无条件的,2. SQl Server会爆出如下错误: 

    The multi-part identifier "A.username" could not be bound. 

    大家可能会说有条件的Join查询本来就不是这样写的,应该写为第二条SQL这样的样子,其实这样写和第三条SQL中使用Outer apply 实现的效果是一样的 

    可是 Outer Apply还能实现如下的效果 
    复制代码代码如下:

    select * from 
    (select * from userino) A 
    OUTER APPLY (select [value] = a.username+'test' ) B 

    这个恐怕直接使用join就有点麻烦了,上面的例子也许没什么意义,其实SQL2005提出Apply连接方法主要是为了在连接查询中使用已经执行的查询语句的结果 

    除了“OUTER APPLY”,SQL Server还有CROSS APPLY,之间的区别主要是在Null值的处理上 

    FOR XML AUTO 主要用于将SQL的查询结果直接返回成XML语句,For Xml 除了auto外 还有RAW和EXPLICIT,详见《超级简单:使用FOR XML AUTO控制XML输出》 

    在文章刚开始提出的SQL文,就是使用了上面的两个特性,首先使用Outer Apply来实现类似于使用userpart进行分组的效果,来分别筛选出各个userpart中的user,然后由于筛选出的结果是多行,所以使用 for xml 来把多行数据拼接成xml,最后很二的对xml进行拆分.... 

    综上,感觉这种实现方式比较独特,又学习了SQL Server中的一些特性,和大家分享一下
    实践:
    表信息:

    id name age address
    1 张三 20 zhangsan
    2 李四 21 lisi
    3 王五 23 wangwu
    4 丽丽 21 lili
    5 吴磊 23 wulei

    select * from(select distinct age from Table_1) A
    outer apply(select [name]=Replace(Replace(REPLACE((select [name] as value from Table_1 N where age=A.age order by N.name asc for XML auto),'"/><N value="','/'),'<N value="',''),'"/>',''))N
    outer apply(select [address]=Replace(Replace(REPLACE((select [address] as value from Table_1 M where age=A.age order by M.name asc for XML auto),'"/><M value="','/'),'<M value="',''),'"/>',''))M
    for XML auto,elements

    查询结果:

    age name address
    20 张三 zhangsan
    21 李四/丽丽 lisi/lili
    23 王五/吴磊 wangwu/wulei

  • 相关阅读:
    Hsl PLC
    .NET平台常用框架整理
    SSH全注解实例详解
    word2vec (CBOW、分层softmax、负采样)
    pandas dataframe 一行变多行 (query pv统计term pv)
    python 按二维数组的某行或列排序 (numpy lexsort)
    基于决策树的分类算法
    【linux】 mail/mutt 发送邮件
    【python】含中文字符串截断
    【python】 判断纯ascii串
  • 原文地址:https://www.cnblogs.com/lvfeilong/p/gcvg7567576.html
Copyright © 2011-2022 走看看