2016-04-11 20 views
1

特定のアプリケーションのユーザーロールのカンマ区切りリストを取得しようとしています。これまではSTUFFFOR XML PATH('')を使用していましたが、このような状況で可能かどうかはわかりません。ここで私は何をしたいのかを示しますが、動作しないクエリは次のとおりです。SQL STUFFを使用してグループ化できない行を連結する

SELECT FName, LName, Email, Username, 
    STUFF((SELECT r.RoleDescription FROM Roles r2 WHERE r2.RoleID = r.RoleID FOR XML PATH('')),1,1,'') as RoleList 
FROM Users u 
INNER JOIN UserRole ur on u.UserID = ur.UserID 
INNER JOIN Roles r on r.RoleID = ur.RoleID 
WHERE ur.AppID = 506 
GROUP BY FName, LName, Email, Username 

これは動作しませんサブクエリのための私のwhere句がGROUP BYにない列が含まれているため。しかし、私がRoleIDでグループ化すると、集計関数でそれらの行を結合する能力が失われます。

これを行うには別の方法がありますか?または、結果を達成するために私のクエリを修正する方法? OUTERが適用

答えて

2

あなたはGROUP次に良く、完全を期すために参加しましたRole

SELECT FName, LName, Email, Username, 
    STUFF(x.csv,1,1,'') as RoleList 
FROM Users u 
INNER JOIN UserRole ur on u.UserID = ur.UserID 
OUTER APPLY 
    (
    SELECT 
     ',' + r.RoleDescription 
    FROM 
     Roles r 
    WHERE 
     r.RoleID = ur.RoleID 
    FOR XML PATH ('') 
    ) x (csv) 
WHERE ur.AppID = 506 

ごとにDISTINCT作品を繰り返さないためにあなたが今してグループを必要としないことがあり、

SELECT FName, LName, Email, Username, 
    STUFF(x.csv,1,1,'') as RoleList 
FROM Users u 
INNER JOIN UserRole ur on u.UserID = ur.UserID 
OUTER APPLY 
    (
    SELECT 
     ',' + r.RoleDescription 
    FROM 
     Roles r 
    WHERE 
     r.RoleID = ur.RoleID 
    FOR XML PATH ('') 
    ) x (csv) 
WHERE ur.AppID = 506 
GROUP BY FName, LName, Email, Username, x.csv 

しかしはるかに滑らかな印象ですこれは実際の値よりもずっと後で適用されるため、インラインのサブクエリではBYを使用します。 RoleIdは、実際の値の一部ではないので、私はまだそれぞれに複数の行を取得しています私たちは、CROSSは

SELECT FName, LName, Email, Username, 
    STUFF(x.csv,1,1,'') as RoleList 
FROM Users u 
CROSS APPLY 
    (
    SELECT 
     ',' + r.RoleDescription 
    FROM 
     UserRole ur 
     JOIN 
     Roles r ON ur.RoleID = r.RoleID 
    WHERE 
     u.UserID = ur.UserID 
    FOR XML PATH ('') 
    ) x (csv) 
WHERE u.UserID IN (Select UserID FROM UserRole WHERE AppID = 506) 
+0

を適用使用できることを意味のUserRoleに実際にあるフィルタ、のためにDISTINCT

更新を中断されません別々の列に各役割を持つ人。彼らがグループ化されているようには見えません。 – joelforsyth

+0

@joelforsyth:おそらくJOINで 'Roles'を残しました。あなたが説明したような複数の行を得ることができるのは唯一の方法です。 'Roles'はAPPLYサブクエリー内になければなりません – gbn

+0

私は両方のクエリを実行しましたが、変更されておらず、ユーザーあたり複数の行があります。 'FName、LName、Email、Usernameを選択します。 FROM Users u INNER JOIN UserRole ur on u.UserID = ur.UserID WHERE ur.AppID = 506'このクエリは、外部からの入力がなくても同じ数の結果を返します。 UserRoleはN:Nテーブルなので – joelforsyth

関連する問題