2009-08-09 2 views
4

私はこれに対する答えを高くて低く探しましたが、わかりません。私は比較的新しいSQL Serverですが、構文がまだまだ下がっていません。私は削除最後のコンマでコースのCONCAT(username, ', ') AS Tagsのように連結している写真のためのすべての写真情報(簡単に)プラス全てのタグを取得する方法を探しています複数の行をSQL​​ Serverの1つの列に連結するにはどうすればよいですか?

 
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  | 

:私は、このデータ構造(単純化)を持っています。私はこれをやろうとしている時間がある。私はthis articleでメソッドを試しましたが、私はDECLAREステートメントを使用することができないというクエリを実行しようとするとエラーが発生します...あなたはどのようにこれを行うことができますか?私はVS08とそれにインストールされているDBを使用しています(私は通常MySQLを使用していますので、実際にDBの味は分かりません... .mdfファイルですか?)

答えて

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 
+0

は、 "インライン"、 "テーブル値"、または "スカラー値"関数ですか?それらはVSが私に与えるオプションです... – Jason

+0

Scalar Valued - 申し訳ありませんが指定しませんでした。 – Eric

+0

ビットを精緻化する:テーブル値関数とインライン関数の両方が型テーブルを返します。これらのオプションは、構文のいくつかを手助けすることですが、このSQLをまっすぐに実行すると、自動的にスカラーになります。 – Eric

13

[OK]を、私はおよそHow do you concat multiple rows into one column in SQL Server?コメント、より好ましい答えを提供することでジャンプする必要があるように私は感じます。

本当に残念ですが、このようなスカラー値関数を使用するとパフォーマンスが低下します。 SQLプロファイラを開いて、テーブルを呼び出すスカラー関数を使用するときに何が起きているかを見てください。

また、連結のための "変数の更新"手法は推奨されていません。将来のバージョンでは機能が継続しない可能性があるためです。

代わりにFOR XML PATHを使用するための文字列連結を行うための好ましい方法です。 XMLパスが作品のため、以下の点を考慮して方法の例については

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; 

、あなたが「ID」と呼ばれる2つのフィールドを持つテーブルと「名」

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コマンド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; 

各写真について、私はタグをつかみ、それらを(順番に)コンマとスペースで連結するサブクエリを持っています。そして、そのサブクエリをstuffコマンドで囲み、コンマとスペースを削除します。

私は誤植をお詫びします。私は実際に自分のマシンにテーブルを作成してこれをテストしていません。

ロブ

+0

+1を働いていますが、実際にはXMLを返します。私はそれを望ましくありません。何らかの理由で元の 'SELECT '、' + username 'を' SELECT TOP(100)PERCENT'、 '+ dbo.users.username AS tags'に変更します... – Jason

+0

"タグとして"取り除きます。 そして、それを関数に入れないでください。そのまま実行してください。実際に何をしましたか? –

+0

"as as"は "as as Expr1"をデフォルトとして配置し、私はそれを関数として実行しなかったので、 "as"を取り除くことはできません。私はそれを標準的なSQLクエリーとして実行しました:\ – Jason

関連する問題