很有意思的SQL多⾏数据拼接
要实现的SQL查询很原始:
要求从第⼀个表进⾏查询得到第⼆个表格式的数据,上⽹查询之后竟然能写出下⾯的SQL:
复制代码代码如下:
lect * from urino
SELECT * FROM(
SELECT DISTINCT urpart
FROM urino
打屁股小孩)A
跳开头的四字成语
OUTER APPLY(
SELECT
[urnames]= replace(replace(replace((SELECT urname as value FROM urino N
WHERE urpart = A.urpart order by n.urname asc FOR XML AUTO),'"/><N value="','/')
,'<N value="',''),'"/>','')
)N
OUTER APPLY(
SELECT
[urname_cns]= replace(replace(replace((SELECT urname_cn as value FROM urino M
WHERE urpart = A.urpart order by m.urname asc FOR XML AUTO),'"/><M value="','/')
,'<M value="',''),'"/>','')
)M
现将SQL进⾏⼀下分析:
总共使⽤到的点有:OUTER APPLY,FOR XML AUTO。由于对SQL Server没有很深的研究,所以记录⼀下
桃胶的功效与作用禁忌OUTER APPLY 是SQL2005开始⽀持的⼀种查询⽅法,类似于连接查询,是将两个查询结果进⾏拼接,但是奇特的是,使⽤OUTER APPLY竟然能够在Apply后⾯的查询中使⽤前⾯已经得到的查询结果。
如:
复制代码代码如下:
lect * from
蛙泳呼吸>查问(lect * from urino) A
cross join (lect urname from urino
where urname = A.urname )B
lect * from
寒咳嗽吃什么好的快
(lect * from urino) A做什么最赚钱
join (lect urname from urino ) B on a.urname = b.urname
lect * from
(lect * from urino) A
OUTER APPLY (lect urname from urino
where urname = A.urname ) B
第⼀段SQL显然是错的,有两个原因:1.Cross Join本来就是⽆条件的,2. SQl Server会爆出如下错误:
The multi-part identifier "A.urname" could not be bound.
⼤家可能会说有条件的Join查询本来就不是这样写的,应该写为第⼆条SQL这样的样⼦,其实这样写和第三条SQL中使⽤Outer apply 实现的效果是⼀样的
可是 Outer Apply还能实现如下的效果
复制代码代码如下:义乌购官网登录
lect * from
(lect * from urino) A
OUTER APPLY (lect [value] = a.urname+'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来实现类似于使⽤urpart进⾏分组的效果,来分别筛选出各个urpart中的ur,然后由于筛选出的结果是多⾏,所以使⽤ for xml 来把多⾏数据拼接成xml,最后很⼆的对xml进⾏拆分....
综上,感觉这种实现⽅式⽐较独特,⼜学习了SQL Server中的⼀些特性,和⼤家分享⼀下