2016-05-02 4 views
1

私はUserIdsとrolenamesのテーブルを持っています。例えばSQLの複数の行にデータを集約する単一の行を返す方法

UserId Rolename 
1  Admin 
1  Editor 
1  Other 
2  Admin 
3  Other 

私は後者の二つの列は、ユーザが「管理者」ロールまたは「編集者」の役割を有しているか否かを示すブール値であるUserId, IsAdmin, IsEditorを含むユーザごとに単一の行を返すようにしたいです。

上記の例から、私は次のような出力になるだろう:

UserId IsAdmin IsEditor 
1  True  True 
2  True  False 
3  False False 

任意の考えを?私はgroup by、sub selectなどで集計関数を使ってさまざまなことを試してきましたが、私はそれを得ていません。

+0

答えとして選択された応答は混乱していますが、その応答の設定は上記の入力と一致していないため、すでに受け入れられています。期待される出力。とにかく、私のコメントの主なポイントは、ibm-ミッドレンジ・タグが正しくまたは間違ってIBM i固有のものとして文書化されているため、タグDB2Iはこのポストのために意図されているようです。そうであれば、そのDB2バリアントで構文が有効でない応答も排除されます。 – CRPence

答えて

1

ユーザー:

UserId UserName 

    1  amir 
    2  john 
    3  sara 

userRoles:

UserId RoleName 

    1  Admin 
    1  Editor 
    2  Editor 

クエリ:

select UserId , 
    (select count(UserRoles.UserId) from userRoles where userRoles.UserId=users.UserId and RoleName='Admin') as IsAdmin , 
    (select count(userRoles.UserId) from userRoles where userRoles.UserId=users.UserId and RoleName='Editor') as IsEditor 
    from users; 

結果:

UserId  IsAdmin IsEditor 
    1   1   1 
    2   0   1 
    3   0   0 
1
with data as (
select 1 userid, 'Admin' rolename from dual union all 
select 1 userid,  'Editor' rolename from dual union all 
select 1 userid,  'Other' rolename from dual union all 
select 2 userid,  'Admin' rolename from dual union all 
select 3 userid,  'Other' rolename from dual 
) 
select userid, 
max(case when rolename = 'Admin' then 'True' else 'False' end) isadmin, 
max(case when rolename = 'Editor' then 'True' else 'False' end) iseditor , 
max(case when rolename = 'Other' then 'True' else 'False' end) isother 
from data 
group by userid 

OUTPUT:

USERID  ISADMIN ISEDITOR ISOTHER 
---------- ------- -------- ------- 
    1  True True  True  
    2  True False False 
    3  False False True  
2

一つの可能​​な解決策:

SELECT 
    UserId, 
    CASE WHEN EXISTS (SELECT * FROM #UserRoles A WHERE A.UserId = UR.UserId AND A.Rolename = 'Admin') THEN 'True' ELSE 'False' END AS IsAdmin, 
    CASE WHEN EXISTS (SELECT * FROM #UserRoles E WHERE E.UserId = UR.UserId AND E.Rolename = 'Editor') THEN 'True' ELSE 'False' END AS IsEditor 
FROM 
    UserRoles UR 
GROUP BY 
    UR.UserId 

ことだ有効な構文は、使用しているSQLの種類に依存するかどうか - Oracleは?あなたは指定しなかった。

もう1つの可能な解決策:

SELECT 
    U.UserId, 
    CASE WHEN A.UserId IS NOT NULL THEN 'True' ELSE 'False' END AS IsAdmin, 
    CASE WHEN E.UserId IS NOT NULL THEN 'True' ELSE 'False' END AS IsEditor 
FROM 
    (
    SELECT DISTINCT 
     UserId 
    FROM 
     UserRoles UR 
    ) U 
LEFT OUTER JOIN UserRoles A ON A.UserId = U.UserId AND A.Rolename = 'Admin' 
LEFT OUTER JOIN UserRoles E ON E.UserId = U.UserId AND E.Rolename = 'Editor' 

は、これらのソリューションはまた、両方のあなたはまったく同じ役割名を持つ同じユーザーIDの複数の行を持っていないことを前提としています。たとえば、表でUser ID 1にAdminを2回入力したとします。

+0

上記の "可能なその他の解決策"は、[2月5日以降に行われた編集の前に] [AND A.Rolename']をコーディングしましたが、意図したとおりに機能するには 'AND E.Rolename 'としてコーディングする必要があります。 FWiW:提供される最初のクエリはまだ静止していますか? DB2 for IBM i SQLの有効な構文ではありません。 ibm-midrangeタグの使用が適切に反映されていると仮定すると、SQL照会はOPによって実行されます。 – CRPence

0

それにはいくつかの方法があります。あなたのテーブルがUSERROLE命名されたと仮定すると、これは私6.1のためのDB2上のサンプルデータで動作します。USERID列は私のテストでINTEGERとして定義されて

....+....1....+....2....+....3... 
     USERID ISADMIN ISEDITOR 
      1 True  True 
      2 True  False 
      3 False False 
******** End of data ******** 

:ようSTRSQLから

WITH adminrole(UserId, RoleName) AS (
    SELECT UserId, RoleName FROM userrole WHERE RoleName = 'Admin'), 

editorrole(UserId, RoleName) AS (
    SELECT UserId, RoleName FROM userrole WHERE RoleName = 'Editor'), 

groupid(UserId) AS (
    SELECT UserId FROM userrole GROUP BY UserId) 

SELECT groupid.UserId, 
     CASE WHEN adminrole.RoleName = 'Admin' 
      THEN 'True' ELSE 'False' END AS IsAdmin, 
     CASE WHEN editorrole.RoleName = 'Editor' 
      THEN 'True' ELSE 'False' END AS IsEditor 
FROM groupid LEFT OUTER JOIN adminrole 
        ON groupid.UserId = adminrole.UserId 
      LEFT OUTER JOIN editorrole 
        ON groupid.UserId = editorrole.UserId 

出力が見えますデータ。

V5R3から現在までのどの場所でも動作します。テーブル名をUSERROLEからテーブル名に変更します。

さまざまな変更を加えることができますが、本当に良い構造が何であるかを知るには詳細が必要です。

関連する問題