很有意思的SQL多行数据拼接

所属分类: 数据库 / MsSql 阅读数: 1589
收藏 0 赞 0 分享

要实现的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中的一些特性,和大家分享一下

更多精彩内容其他人还在看

SQL Server评估期已过问题的解决方法

这篇文章主要为大家详细介绍了SQL Server评估期已过问题的解决方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

sqlserver还原数据库的时候出现提示无法打开备份设备的解决方法(设备出现错误或设备脱)

今天在恢复数据库的时候,因为是异地部分还原,出现提示 无法打开备份设备 E:\自动备份\ufidau8xTmp\UFDATA.BAK 。设备出现错误或设备脱,这里分享一下解决方法,需要的朋友可以参考一下
收藏 0 赞 0 分享

SQL数据库存储过程示例解析

这篇文章主要针对SQL数据库存储过程示例进行解析,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SQL Server 2012 安全概述

这篇文章给你概括介绍了SQL Server 2012里的基本安全概念。你学到了一些常见的数据威胁,探寻了SQL Server背后的设计理念,学习了在整个系列文章看到的一些安全术语,算是一篇比较非公式化的开篇,希望能够勾引起大家对于sql安全的兴趣
收藏 0 赞 0 分享

探讨select in 在postgresql的效率问题

这篇文章主要介绍了探讨select in 在postgresql的效率问题 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

SQL Server 2012 身份验证(Authentication)

这篇SQL Server安全文章,我们学习了SQL Server里的多个验证选项。Windows集成身份验证是最安全的,但并不是都是可行的,微软多年来已经让SQL Server验证更加安全。
收藏 0 赞 0 分享

SQL性能优化之定位网络性能问题的方法(DEMO)

这篇文章主要介绍了SQL性能优化之定位网络性能问题的方法的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

SQL Server 2016里的sys.dm_exec_input_buffer的问题

这篇文章主要介绍了SQL Server 2016里的sys.dm_exec_input_buffer的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

SQL Server删除表及删除表中数据的方法

本文介绍SQL Server中如何删除表,如何删除表中的数据。在删除表数据时有delete和truncate两种方法,delete和truncate有什么区别呢
收藏 0 赞 0 分享

sqlserver 因为选定的用户拥有对象,所以无法除去该用户的解决方法

这篇文章主要介绍了sqlserver 因为选定的用户拥有对象,所以无法除去该用户,因为是附加数据库选择了与源服务器一样的用户导致
收藏 0 赞 0 分享
查看更多