我已经搜索了这个问题的答案,但我无法弄明白。我对SQL Server比较陌生,但还没有很好的语法。我有这个数据结构(简化):
Table "Users" | Table "Tags": UserID UserName | TagID UserID PhotoID 1 Bob | 1 1 1 2 Bill | 2 2 1 3 Jane | 3 3 1 4 Sam | 4 2 2 ----------------------------------------------------- Table "Photos": | Table "Albums": PhotoID UserID AlbumID | AlbumID UserID 1 1 1 | 1 1 2 1 1 | 2 3 3 1 1 | 3 2 4 3 2 | 5 3 2 |
我正在寻找一种方法来获取所有照片信息(简单)以及该照片的所有标记,例如CONCAT(username, ', ') AS Tags
,最后删除了最后一个逗号。我有一段时间试图这样做。我在this article中尝试了这个方法,但是当我尝试运行查询说我不能使用DECLARE
语句时出现错误...你们有什么想法吗?做了什么?我正在使用VS08和其中安装的数据库(我通常使用MySQL,所以我不知道这是什么类型的DB真的是......它是一个.mdf文件?)
答案 0 :(得分:13)
好的,我觉得我需要加入评论How do you concat multiple rows into one column in SQL Server?并提供更优选的答案。
我很抱歉,但使用这样的标量值函数会导致性能下降。只需打开SQL事件探查器,看一下使用调用表的标量函数时会发生什么。
此外,不鼓励使用“更新变量”技术进行连接,因为该功能在将来的版本中可能不会继续。
执行字符串连接以使用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如何工作的示例,请考虑以下内容,假设您有一个包含两个名为“id”和“name”的字段的表
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>
如果你输入一个空的PATH字符串,你就更接近普通的字符串连接:
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命令进来.STUFF(s,x,n,s2)从位置x开始拉出s的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命令中包围该子查询以去除前导逗号和空格。
我为任何拼写错误道歉 - 我实际上并没有在自己的机器上创建表来测试它。
罗布
答案 1 :(得分:3)
我要创建一个UDF:
create function GetTags(PhotoID int) returns @tags varchar(max)
as
begin
declare @mytags varchar(max)
set @mytags = ''
select @mytags = @mytags + ', ' + tag from tags where photoid = @photoid
return substring(@mytags, 3, 8000)
end
然后,您所要做的就是:
select GetTags(photoID) as tagList from photos
答案 2 :(得分:0)
Street_Name ; Street_Code
如果要显示两个不同的行concat本身,怎么办? (我的意思是我想从选择结果中显示最后一行。我的表有第一条记录和第二条记录)