[英]How to return a single row aggregating data in multiple rows in SQL
我有一個用戶ID和角色名稱表。
例如:
UserId Rolename
1 Admin
1 Editor
1 Other
2 Admin
3 Other
我想為每個用戶返回一行,其中包含UserId, IsAdmin, IsEditor
,其中后兩列是布爾值,代表用戶是否具有“ Admin”角色或“ Editor”角色。
從上面的示例中,我將獲得以下輸出:
UserId IsAdmin IsEditor
1 True True
2 True False
3 False False
有什么想法嗎? 我一直在嘗試各種功能,包括聚合功能,分組依據,子選擇等,但我只是沒有得到。
一種可能的解決方案:
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? 您沒有指定。
另一個可能的解決方案:
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包含多行。 例如,表中兩次使用Admin的用戶ID 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
輸出:
USERID ISADMIN ISEDITOR ISOTHER
---------- ------- -------- -------
1 True True True
2 True False False
3 False False True
用戶:
UserId UserName
1 amir
2 john
3 sara
用戶角色:
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
有幾種方法可以做到這一點。 假設您的表名為USERROLE,這可以與DB2 for i 6.1上的樣本數據一起使用:
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
STRSQL的輸出如下所示:
....+....1....+....2....+....3...
USERID ISADMIN ISEDITOR
1 True True
2 True False
3 False False
******** End of data ********
在我的測試數據中,USERID列定義為INTEGER。
從V5R3到最新版本都可以使用。 將表名從USERROLE更改為您的表名。
可以進行各種更改,但是需要更多信息才能知道什么是真正的好結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.