好吧,我覺得我需要跳轉到評論有關How do you concat multiple rows into one column in SQL Server?,並提供一個更優選的答案。
我真的很抱歉,但使用像這樣的標量值函數會導致性能下降。只需打開SQL Profiler並查看當您使用調用表的標量函數時發生了什麼。
另外,不鼓勵「連接更新變量」技術,因爲該功能在未來的版本中可能不會繼續。
改爲使用FOR XML PATH進行字符串連接的首選方式。
select
stuff((select ', ' + t.tag from tags t where t.photoid = p.photoid order by tag for xml path('')),1,2,'') as taglist
,*
from photos
order by photoid;
有關如何FOR XML PATH的作品,請考慮以下,想象你有兩個字段的表稱爲 '身份證' 和 '名'
SELECT id, name
FROM table
order by name
FOR XML PATH('item'),root('itemlist')
;
給出一些例子:
<itemlist><item><id>2</id><name>Aardvark</a></item><item><id>1</id><name>Zebra</name></item></itemlist>
但是如果你遺漏ROOT,你會得到一些稍微不同的東西:
SELECT id, name
FROM table
order by name
FOR XML PATH('item')
;
<item><id>2</id><name>Aardvark</a></item><item><id>1</id><name>Zebra</name></item>
如果你把一個空的路徑字符串,你會得到更接近普通字符串連接:
SELECT id, name
FROM table
order by name
FOR XML PATH('')
;
<id>2</id><name>Aardvark</a><id>1</id><name>Zebra</name>
現在到了真正棘手位......如果你的名字開始與一個@符號欄,就變成一個屬性,如果一列沒有名稱(或你叫它[*]),那麼它留下的是太多的標籤:
SELECT ',' + name
FROM table
order by name
FOR XML PATH('')
;
,Aardvark,Zebra
如今終於,剝奪領先逗號,東東命令STUFF(s,x,n,s2)從位置x開始拉出n個字符。取而代之的是s2。所以:
SELECT STUFF('abcde',2,3,'123456');
給出:
a123456e
所以現在看看我上面的查詢您的標記列表。
select
stuff((select ', ' + t.tag from tags t where t.photoid = p.photoid order by tag for xml path('')),1,2,'') as taglist
,*
from photos
order by photoid;
對於每張照片,我有抓住標籤和與commma和一個空間連接它們(按順序)的子查詢。然後,我用stuff命令將該子查詢包圍起來,以去掉前導逗號和空格。
對於任何錯別字,我表示歉意 - 我沒有在我自己的機器上真正創建表來測試它。
Rob
是「內聯」,「表值」還是「標量值」函數?這些是VS給我的選項... – Jason 2009-08-09 03:07:17
標量值 - 抱歉,我沒有指定。 – Eric 2009-08-09 03:07:43
詳細闡述一下:表值和內聯函數都返回類型表。這些選項可以幫助您掌握一些語法,但如果您直接運行此SQL,它將自動成爲標量。 – Eric 2009-08-09 03:14:18