(轉(zhuǎn))關(guān)于SQL Server 中合并行的方法
-------------參考------------------------
----假設(shè)我們有如下數(shù)據(jù)表
------菜系表------------
--店名 菜系------
--澳門豆撈 川菜
--澳門豆撈 粵菜
--澳門豆撈 閩菜
--為民大酒店 魯菜
--為民大酒店 粵菜
--為民大酒店 川菜
-----------------------
-------執(zhí)行如下語句
select 店名,菜系=STUFF((select ','+ltrim(菜系) from 菜系表 where 店名=t.店名 for XML path('')),1,1,'')
from 菜系表 t
group by 店名
-------結(jié)果如下-------------
--店名 菜系----------
--澳門豆撈 川菜,閩菜,粵菜
--為民大酒店 川菜,魯菜,粵菜
----------------------------
--------------------------------------------------------------------------------------
Stuff(expression1_Str,startIndex,lengthInt,expression2_Str)函數(shù)共有四個參數(shù),
其功能是將expression1_Str中自startIndex位置起刪除lengthInt個字符,然后將expression2插入到expression1_Str中的startIndex位置。startIndex 從1開始
數(shù)據(jù)庫表中有三個字段,要以xxxx-xxxxxx-xxxxxx的格式輸出,其中不滿相應(yīng)位數(shù)的,在后面補(bǔ)空格,即把類似23,1234,879這樣的三個數(shù)以如下形式輸出到報(bào)表中:23__-1234__-879___的格式輸出,標(biāo)注顏色的下劃線一種顏色代表一個空格。
STUFF(SPACE(4),1,LEN(‘23’),’23’)+’-’+STUFF(SPACE(6),1,LEN(‘1234’),’1234’)+’-’+ STUFF(SPACE(6),1,LEN(‘879’),’879’),轉(zhuǎn)換結(jié)果自然就為23__-1234__-879___了。
Stuff函數(shù)另一種解釋
select stuff('string1',<starting position>,<length to delete from string 1>,'string2')
示例:
select stuff('youxiaofeng',2,1,'F')
從第二個字符開始,刪掉一個字符,然后用'F'代替刪掉字符的位置,如果不需要刪掉字符,則將<length to delete from string 1>設(shè)為0即可。
注意:如果<starting position>或<length to delete from string 1 >是負(fù)的,或者<starting position>是大于<string 1>長度的數(shù),則STUFF函數(shù)將返回NULL,如果指令的<length to delete from string 1>長于從<starting position>位置到<string 1>結(jié)尾的字符數(shù),此函數(shù)將<string 1 >在<starting position-1>處截?cái)?br>
---------------------------------------------------------------------------
FOR XML PATH 語句的應(yīng)用
大家都知道在SQL Server中利用 FOR XML PATH 語句能夠把查詢的數(shù)據(jù)生成XML數(shù)據(jù),下面是它的一些應(yīng)用示例。
DECLARE @TempTable table(UserID int , UserName nvarchar(50));
insert into @TempTable (UserID,UserName) values (1,'a')
insert into @TempTable (UserID,UserName) values (2,'b')
select UserID,UserName from @TempTable FOR XML PATH
運(yùn)行這段腳本,將生成如下結(jié)果:
<row>
<UserID>1</UserID>
<UserName>a</UserName>
</row>
<row>
<UserID>2</UserID>
<UserName>b</UserName>
</row>
大家可以看到兩行數(shù)據(jù)生成了兩個節(jié)點(diǎn),修改一下PATH的參數(shù):
select UserID,UserName from @TempTable FOR XML PATH('lzy')
再次運(yùn)行上述腳本,將生成如下的結(jié)果:
<lzy>
<UserID>1</UserID>
<UserName>a</UserName>
</lzy>
<lzy>
<UserID>2</UserID>
<UserName>b</UserName>
</lzy>
可以看到節(jié)點(diǎn)變成,其實(shí)PATH() 括號內(nèi)的參數(shù)是控制節(jié)點(diǎn)名稱的,這樣的話大家可以看一下如果是空字符串(不是沒有參數(shù))會是什么結(jié)果?
select UserID,UserName from @TempTable FOR XML PATH('')
執(zhí)行上面這段腳本將生成結(jié)果:
<UserID>1</UserID>
<UserName>a</UserName>
<UserID>2</UserID>
<UserName>b</UserName>
這樣就不顯示上級節(jié)點(diǎn)了,大家知道在 PATH 模式中,列名或列別名被作為 XPath 表達(dá)式來處理,也就是說,是列的名字,這樣大膽試驗(yàn)一下不給指定列名和別名會是怎么樣?
select CAST(UserID AS varchar) + '',UserName + '' from @TempTable FOR XML PATH('')
運(yùn)行上面這句將生成結(jié)果
1a2b
所有數(shù)據(jù)都生成一行,而且還沒有連接字符,這樣的數(shù)據(jù)可能對大家沒有用處,還可以再變化一下:
select CAST(UserID AS varchar) + ',',UserName + '',';' from @TempTable FOR XML PATH('')
生成結(jié)果
1,a;2,b;
大家現(xiàn)在明白了吧,可以通過控制參數(shù)來生成自己想要的結(jié)果,例如:
select '{' + CAST(UserID AS varchar) + ',','"' +UserName + '"','}' from @TempTable FOR XML PATH('')
生成結(jié)果
{1,"a"}{2,"b"}
還可以生成其他格式,大家可以根據(jù)自己需要的格式進(jìn)行組合。
下面是一個數(shù)據(jù)統(tǒng)計(jì)的應(yīng)用,希望大家可以通過下面的實(shí)例想到更多的應(yīng)用
DECLARE @T1 table(UserID int , UserName nvarchar(50),CityName nvarchar(50));
insert into @T1 (UserID,UserName,CityName) values (1,'a','上海')
insert into @T1 (UserID,UserName,CityName) values (2,'b','北京')
insert into @T1 (UserID,UserName,CityName) values (3,'c','上海')
insert into @T1 (UserID,UserName,CityName) values (4,'d','北京')
insert into @T1 (UserID,UserName,CityName) values (5,'e','上海')
SELECT B.CityName,LEFT(UserList,LEN(UserList)-1) FROM (
SELECT CityName,
(SELECT UserName+',' FROM @T1 WHERE CityName=A.CityName FOR XML PATH('')) AS UserList
FROM @T1 A
GROUP BY CityName
) B
生成結(jié)果(每個城市的用戶名)
北京 b,d
上海 a,c,e
----假設(shè)我們有如下數(shù)據(jù)表
------菜系表------------
--店名 菜系------
--澳門豆撈 川菜
--澳門豆撈 粵菜
--澳門豆撈 閩菜
--為民大酒店 魯菜
--為民大酒店 粵菜
--為民大酒店 川菜
-----------------------
-------執(zhí)行如下語句
select 店名,菜系=STUFF((select ','+ltrim(菜系) from 菜系表 where 店名=t.店名 for XML path('')),1,1,'')
from 菜系表 t
group by 店名
-------結(jié)果如下-------------
--店名 菜系----------
--澳門豆撈 川菜,閩菜,粵菜
--為民大酒店 川菜,魯菜,粵菜
----------------------------
--------------------------------------------------------------------------------------
Stuff(expression1_Str,startIndex,lengthInt,expression2_Str)函數(shù)共有四個參數(shù),
其功能是將expression1_Str中自startIndex位置起刪除lengthInt個字符,然后將expression2插入到expression1_Str中的startIndex位置。startIndex 從1開始
數(shù)據(jù)庫表中有三個字段,要以xxxx-xxxxxx-xxxxxx的格式輸出,其中不滿相應(yīng)位數(shù)的,在后面補(bǔ)空格,即把類似23,1234,879這樣的三個數(shù)以如下形式輸出到報(bào)表中:23__-1234__-879___的格式輸出,標(biāo)注顏色的下劃線一種顏色代表一個空格。
STUFF(SPACE(4),1,LEN(‘23’),’23’)+’-’+STUFF(SPACE(6),1,LEN(‘1234’),’1234’)+’-’+ STUFF(SPACE(6),1,LEN(‘879’),’879’),轉(zhuǎn)換結(jié)果自然就為23__-1234__-879___了。
Stuff函數(shù)另一種解釋
select stuff('string1',<starting position>,<length to delete from string 1>,'string2')
示例:
select stuff('youxiaofeng',2,1,'F')
從第二個字符開始,刪掉一個字符,然后用'F'代替刪掉字符的位置,如果不需要刪掉字符,則將<length to delete from string 1>設(shè)為0即可。
注意:如果<starting position>或<length to delete from string 1 >是負(fù)的,或者<starting position>是大于<string 1>長度的數(shù),則STUFF函數(shù)將返回NULL,如果指令的<length to delete from string 1>長于從<starting position>位置到<string 1>結(jié)尾的字符數(shù),此函數(shù)將<string 1 >在<starting position-1>處截?cái)?br>
---------------------------------------------------------------------------
FOR XML PATH 語句的應(yīng)用
大家都知道在SQL Server中利用 FOR XML PATH 語句能夠把查詢的數(shù)據(jù)生成XML數(shù)據(jù),下面是它的一些應(yīng)用示例。
DECLARE @TempTable table(UserID int , UserName nvarchar(50));
insert into @TempTable (UserID,UserName) values (1,'a')
insert into @TempTable (UserID,UserName) values (2,'b')
select UserID,UserName from @TempTable FOR XML PATH
運(yùn)行這段腳本,將生成如下結(jié)果:
<row>
<UserID>1</UserID>
<UserName>a</UserName>
</row>
<row>
<UserID>2</UserID>
<UserName>b</UserName>
</row>
大家可以看到兩行數(shù)據(jù)生成了兩個節(jié)點(diǎn),修改一下PATH的參數(shù):
select UserID,UserName from @TempTable FOR XML PATH('lzy')
再次運(yùn)行上述腳本,將生成如下的結(jié)果:
<lzy>
<UserID>1</UserID>
<UserName>a</UserName>
</lzy>
<lzy>
<UserID>2</UserID>
<UserName>b</UserName>
</lzy>
可以看到節(jié)點(diǎn)變成,其實(shí)PATH() 括號內(nèi)的參數(shù)是控制節(jié)點(diǎn)名稱的,這樣的話大家可以看一下如果是空字符串(不是沒有參數(shù))會是什么結(jié)果?
select UserID,UserName from @TempTable FOR XML PATH('')
執(zhí)行上面這段腳本將生成結(jié)果:
<UserID>1</UserID>
<UserName>a</UserName>
<UserID>2</UserID>
<UserName>b</UserName>
這樣就不顯示上級節(jié)點(diǎn)了,大家知道在 PATH 模式中,列名或列別名被作為 XPath 表達(dá)式來處理,也就是說,是列的名字,這樣大膽試驗(yàn)一下不給指定列名和別名會是怎么樣?
select CAST(UserID AS varchar) + '',UserName + '' from @TempTable FOR XML PATH('')
運(yùn)行上面這句將生成結(jié)果
1a2b
所有數(shù)據(jù)都生成一行,而且還沒有連接字符,這樣的數(shù)據(jù)可能對大家沒有用處,還可以再變化一下:
select CAST(UserID AS varchar) + ',',UserName + '',';' from @TempTable FOR XML PATH('')
生成結(jié)果
1,a;2,b;
大家現(xiàn)在明白了吧,可以通過控制參數(shù)來生成自己想要的結(jié)果,例如:
select '{' + CAST(UserID AS varchar) + ',','"' +UserName + '"','}' from @TempTable FOR XML PATH('')
生成結(jié)果
{1,"a"}{2,"b"}
還可以生成其他格式,大家可以根據(jù)自己需要的格式進(jìn)行組合。
下面是一個數(shù)據(jù)統(tǒng)計(jì)的應(yīng)用,希望大家可以通過下面的實(shí)例想到更多的應(yīng)用
DECLARE @T1 table(UserID int , UserName nvarchar(50),CityName nvarchar(50));
insert into @T1 (UserID,UserName,CityName) values (1,'a','上海')
insert into @T1 (UserID,UserName,CityName) values (2,'b','北京')
insert into @T1 (UserID,UserName,CityName) values (3,'c','上海')
insert into @T1 (UserID,UserName,CityName) values (4,'d','北京')
insert into @T1 (UserID,UserName,CityName) values (5,'e','上海')
SELECT B.CityName,LEFT(UserList,LEN(UserList)-1) FROM (
SELECT CityName,
(SELECT UserName+',' FROM @T1 WHERE CityName=A.CityName FOR XML PATH('')) AS UserList
FROM @T1 A
GROUP BY CityName
) B
生成結(jié)果(每個城市的用戶名)
北京 b,d
上海 a,c,e

浙公網(wǎng)安備 33010602011771號