准備工作:
CREATE TABLE [dbo].[Students]( [id] [int] IDENTITY(1,1) NOT NULL, [names] [varchar](50) NULL, [hobby] [varchar](50) NULL )
insert into students values('張三','書法'),('張三','籃球'),('張三','台球'),('李四','書法'),('李四','唱歌'),('李四','足球'),('李四','乒乓球')
|
for xml path
把查詢結果用xml表現出來。
1 正常的查詢:
select * from Students
結果是:
id names hobby
----------- --------------------------------------------------
1 張三 書法
2 張三 籃球
3 張三 台球
4 李四 書法
5 李四 唱歌
6 李四 足球
7 李四 乒乓球
返回的是一個數據表格(多條)。
2 用xml表現
select * from Students for xml path
結果是:
XML_F52E2B61-18A1-11d1-B105-00805F49916B
------------------------------------------------------------------------------------
<row><id>1</id><names>張三</names><hobby>書法</hobby></row><row><id>2</id><names>張三</names><hobby>籃球</hobby></row
><row><id>3</id><names>張三</names><hobby>台球</hobby></row><row><id>4</id><names>李四</names><hobby>書法</hobby></row>
<row><id>5</id><names>李四</names><hob
也是一個數據表格(單條)
把查詢結果做為xml數據格式返回了一行數據。
3 通過使用path()參數,可改變列節點:
select * from Students for xml path('')
結果:
XML_F52E2B61-18A1-11d1-B105-00805F49916B
-----------------------------------------------------------------------------------
<id>1</id><names>張三</names><hobby>書法</hobby><id>2</id><names>張三</names><hobby>籃球</hobby>
<id>3</id><names>張三</names><hobby>台球</hobby><id>4</id><names>李四</names><hobby>書法</hobby>
<id>5</id><names>李四</names><hobby>唱歌</hobby><id>6</id><names>李四</names><hobby>足球
使用path(‘’)空參數,去掉了row節點,直接顯示的是兩個屬性字段。
4 自定義節點
select * from Students for xml path('selfNode')
結果如下:
XML_F52E2B61-18A1-11d1-B105-00805F49916B
--------------------------------------------------------------------------------------------
<selfNode><id>1</id><names>張三</names><hobby>書法</hobby></selfNode>
<selfNode><id>2</id><names>張三</names><hobby>籃球</hobby></selfNode>
<selfNode><id>3</id><names>張三</names><hobby>台球</hobby></selfNode>
<selfNode><id>4</id><names>李四</names><hobby>書法</hobby></selfNode>
總的來說,for xml path返回的是一條數據(一個xml字串)。所以,這個可以作為查詢中的一列。如下:
select distinct aaa.names,hobby=(
SELECT hobby+',' FROM students
WHERE names=aaa.names
FOR XML PATH('')
)
from students aaa
結果如下:
names hobby
--------------------------------------------------
李四 書法,唱歌,足球,乒乓球,
張三 書法,籃球,台球,
從students表中查詢names,且各自的hobby,hobby是多條記錄,通過xml 整合到一條記錄,並使用逗點分隔。
上面的語句中有一句:where names=aaa.names,因為for xml path返回的是一條數據字串,不能進行查詢條件的關聯,即不能做為數據表與其它表進行關聯。
它只返回一行一列,且for xml path都整合到一字符串中而沒有其它字段,所以不能與其它表進行聯合查詢。但可以在for xml之前進行聯合查詢,如下:
select distinct aaa.names,hobby=(
select hobby+',' FROM students
where names=aaa.names
for xml path('')
) from students aaa
for xml path部分的結果做為一個字段顯示,而粗體部分表示把每個names中的hobby字段通過逗號連成一個字段,如下:
names hobby
--------------------------------------------------
李四 書法,唱歌,足球,乒乓球,
張三 書法,籃球,台球,
未使用distinct,結果如下:
names hobby
--------------------------------------------------
張三 書法,籃球,台球,
張三 書法,籃球,台球,
張三 書法,籃球,台球,
李四 書法,唱歌,足球,乒乓球,
李四 書法,唱歌,足球,乒乓球,
李四 書法,唱歌,足球,乒乓球,
李四 書法,唱歌,足球,乒乓球,
把重復的去掉,可通過group或distinct去掉
另外:對於可容忍的臟讀而不死鎖的with onlock在mssql中可在表后邊使用with(nolock)臟讀;今天查了一下,對於mysql來說,不需要使用with nolock,會自動使用nolock. 。這個我自己未做過測試,大概只是了解一下。