很有意思的SQL多行數(shù)據(jù)拼接
要實(shí)現(xiàn)的SQL查詢很原始:

要求從第一個(gè)表進(jìn)行查詢得到第二個(gè)表格式的數(shù)據(jù),上網(wǎng)查詢之后竟然能寫出下面的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
現(xiàn)將SQL進(jìn)行一下分析:
總共使用到的點(diǎn)有:OUTER APPLY,F(xiàn)OR XML AUTO。由于對(duì)SQL Server沒(méi)有很深的研究,所以記錄一下
OUTER APPLY 是SQL2005開(kāi)始支持的一種查詢方法,類似于連接查詢,是將兩個(gè)查詢結(jié)果進(jìn)行拼接,但是奇特的是,使用OUTER APPLY竟然能夠在Apply后面的查詢中使用前面已經(jīng)得到的查詢結(jié)果。
如:
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顯然是錯(cuò)的,有兩個(gè)原因:1.Cross Join本來(lái)就是無(wú)條件的,2. SQl Server會(huì)爆出如下錯(cuò)誤:
The multi-part identifier "A.username" could not be bound.
大家可能會(huì)說(shuō)有條件的Join查詢本來(lái)就不是這樣寫的,應(yīng)該寫為第二條SQL這樣的樣子,其實(shí)這樣寫和第三條SQL中使用Outer apply 實(shí)現(xiàn)的效果是一樣的
可是 Outer Apply還能實(shí)現(xiàn)如下的效果
select * from
(select * from userino) A
OUTER APPLY (select [value] = a.username+'test' ) B
這個(gè)恐怕直接使用join就有點(diǎn)麻煩了,上面的例子也許沒(méi)什么意義,其實(shí)SQL2005提出Apply連接方法主要是為了在連接查詢中使用已經(jīng)執(zhí)行的查詢語(yǔ)句的結(jié)果
除了“OUTER APPLY”,SQL Server還有CROSS APPLY,之間的區(qū)別主要是在Null值的處理上
FOR XML AUTO 主要用于將SQL的查詢結(jié)果直接返回成XML語(yǔ)句,F(xiàn)or Xml 除了auto外 還有RAW和EXPLICIT,詳見(jiàn)《超級(jí)簡(jiǎn)單:使用FOR XML AUTO控制XML輸出》
在文章剛開(kāi)始提出的SQL文,就是使用了上面的兩個(gè)特性,首先使用Outer Apply來(lái)實(shí)現(xiàn)類似于使用userpart進(jìn)行分組的效果,來(lái)分別篩選出各個(gè)userpart中的user,然后由于篩選出的結(jié)果是多行,所以使用 for xml 來(lái)把多行數(shù)據(jù)拼接成xml,最后很二的對(duì)xml進(jìn)行拆分....
綜上,感覺(jué)這種實(shí)現(xiàn)方式比較獨(dú)特,又學(xué)習(xí)了SQL Server中的一些特性,和大家分享一下
相關(guān)文章
sum(case when then)(判斷男女生的個(gè)數(shù))
判斷類似一個(gè)班級(jí)的男生和女生的人數(shù)使用sum (cese when then)示例代碼如下,感興趣的朋友可以參考下2013-09-09
SQL Server約束增強(qiáng)的兩點(diǎn)建議
我們可以在CHECK的約束條件中加入任何邏輯表達(dá)式,而目前所有外鍵只能用來(lái)驗(yàn)證一個(gè)或多個(gè)列的值是否相等。2009-05-05
分組后分組合計(jì)以及總計(jì)SQL語(yǔ)句(稍微整理了一下)
這篇文章主要介紹了分組后分組合計(jì)以及總計(jì)SQL語(yǔ)句,需要的朋友可以參考下2017-02-02
SQL Server 不存在或訪問(wèn)被拒絕(轉(zhuǎn))
在使用 SQL Server 的過(guò)程中,用戶遇到最多的問(wèn)題莫過(guò)于連接失敗了。一般而言,有兩種連接SQL Server 的方式,一是利用 SQL Server 自帶的客戶端工具2009-06-06
SqlServer?多種分頁(yè)方式?詳解(含簡(jiǎn)單速度測(cè)試)
這篇文章主要介紹了SqlServer?多種分頁(yè)方式?(含簡(jiǎn)單速度測(cè)試),附帶50萬(wàn)數(shù)據(jù)分頁(yè)時(shí)間[本機(jī)訪問(wèn)|已重啟SQL服務(wù)|無(wú)其他程序干擾][非索引排序],需要的朋友可以參考下2022-12-12
SQL SERVER 與ACCESS、EXCEL的數(shù)據(jù)轉(zhuǎn)換方法分享
熟悉SQL SERVER 2000的數(shù)據(jù)庫(kù)管理員都知道,其DTS可以進(jìn)行數(shù)據(jù)的導(dǎo)入導(dǎo)出,其實(shí),我們也可以使用Transact-SQL語(yǔ)句進(jìn)行導(dǎo)入導(dǎo)出操作2012-02-02
SQL Server查詢數(shù)據(jù)庫(kù)中表使用空間信息實(shí)現(xiàn)腳本
這篇文章主要介紹了SQL Server查詢數(shù)據(jù)庫(kù)中表使用空間信息實(shí)現(xiàn)腳本,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-07-07
在安裝了Sql2000的基礎(chǔ)上安裝Sql2005的詳細(xì)過(guò)程 圖文
在安裝了Sql2000的基礎(chǔ)上安裝Sql2005的詳細(xì)過(guò)程 圖文方法,需要的朋友可以參考下。2011-03-03

