簡體   English   中英

如何在SQL Server中將多行連接成一列?

[英]How do you concat multiple rows into one column in SQL Server?

我已經高低搜索了這個答案,但我無法弄明白。 我對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當然刪除了最后一個逗號。 我有一段時間試圖這樣做。 我已經嘗試了本文中的方法,但是當我嘗試運行查詢說我無法使用DECLARE語句時出現錯誤...你們有任何想法如何做到這一點? 我正在使用VS08和其中安裝的任何數據庫(我通常使用MySQL,所以我不知道這是什么類型的DB真的是......它是一個.mdf文件?)

好吧,我覺得我需要深入評論如何在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命令中包圍該子查詢以去除前導逗號和空格。

我為任何打字錯誤道歉 - 我實際上並沒有在我自己的機器上創建表來測試它。

我要創建一個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
Street_Name   ; Street_Code

  1. 西 | 14
  2. | 7
  3. 西+東| 714

如果要顯示兩個不同的行連續本身,怎么辦呢? (我的意思是我想從選擇結果顯示的最后一行。我的表有第一和第二條記錄)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM