sql server的for xml path與變通的行轉列


SQL Server中有提供一個FOR XML PATH的子句(不知道能不能叫函數),用來將查詢結果行輸出成XML格式,我們可以通過這個語法做一些變通實現一些特定的功能,比如說行轉列。要會變通的話,當然首先是要知道FOR XML PATH的語法。

FOR XML PATH的簡單語法

假設有一個hobby表(愛好),表中有兩個字段,一個是hobbyID(愛好id),一個是hName(愛好名稱)。

這樣,我們執行一條最簡單的帶FOR XML PATH子句的SQL語句,看看查詢出來的結果。

SELECT * FROM hobby FOR XML PATH;
<row>
  <hobbyID>1</hobbyID>
  <hName>爬山</hName>
</row>
<row>
  <hobbyID>2</hobbyID>
  <hName>游泳</hName>
</row>
<row>
  <hobbyID>3</hobbyID>
  <hName>美食</hName>
</row>

由結果可見FOR XML PATH子句可以將查詢結果行輸出成XML格式。

FOR XML PATH的變通

更多的,FOR XML PATH子句是支持傳遞參數的,即FOR XML PATH(schema),這樣的話在查詢的時候就會將行標簽<row>替換為<schema>,要注意的是schema必須是字符串。

SELECT * FROM hobby FOR XML PATH('yanggb');
<yanggb>
  <hobbyID>1</hobbyID>
  <hName>爬山</hName>
</yanggb>
<yanggb>
  <hobbyID>2</hobbyID>
  <hName>游泳</hName>
</yanggb>
<yanggb>
  <hobbyID>3</hobbyID>
  <hName>美食</hName>
</yanggb>

這時候,就可以利用XML的特點,即空標簽不會存在的特定,將行標簽<row>去掉。

SELECT * FROM hobby FOR XML PATH('');
<hobbyID>1</hobbyID>
<hName>爬山</hName>
<hobbyID>2</hobbyID>
<hName>游泳</hName>
<hobbyID>3</hobbyID>
<hName>美食</hName>

那能更改/去除行標簽<row>,能不能更改/去除列標簽呢?答案是可以的,可以通過給列起別名的方式來更改/除列標簽。要注意的是這里的別名也必須是字符串。

SELECT hobbID AS AA, hName AS BB FROM hobby FOR XML PATH('');
<AA>1</AA>
<BB>爬山</BB>
<AA>2</AA>
<BB>游泳</BB>
<AA>3</AA>
<BB>美食</BB>

與去除行標簽<row>的方式不一樣的是,去除列標簽不能將別名定義為空字符串,否則數據庫引擎會報錯誤:[Err] 42000 - [SQL Server]缺少對象或列名,或者對象或列名為空。對於 SELECT INTO 語句,請確保每列均具有名稱。對於其他語句,請查找空的別名。不允許使用定義為 "" 或 [] 的別名。請將別名更改為有效名稱。

那么要怎么去除列標簽呢,做法是給字段加上空字符串(加任何字符串都可以,我的理解是這種做法修改了列值,在沒有起別名的情況下,原來的列標簽不再匹配列值,數據庫引擎會將自動該列標簽去除)。

SELECT hobbID + '', hName + '' FROM hobby FOR XML PATH('');
1爬山2游泳3美食

FOR XML PATH實現行轉列

根據上面的FOR XML PATH的變通的內容,我們就可以來實現行轉列了。

SELECT
    hName, 
    (SELECT ',' + hName FROM hobby FOR XML PATH('')) AS hNames
FROM hobby FOR XML PATH('');

這樣我們就能得到一個所有愛好拼接起來的列hNames。

這時候我們會發現hNames字段值多了一個逗號,使用STUFF函數(推薦)或REPLACE函數去除即可。

更多的,可以在FOR XML PATH子句前添加WHERE子句限定條件范圍來限定行轉列的范圍(也可以使用自連接限定當前行轉列的范圍)。

當然了,SQL SERVER還提供了另外的行轉列的PRIVOT函數和列轉行的UNPRIVOT函數。

 

"一個姑娘不會因為你專一痴情就喜歡你,只會因為你優秀而喜歡你。"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM