如何 return 单行聚合 SQL 中多行的数据
How to return a single row aggregating data in multiple rows in SQL
我有 table 个 UserId 和角色名。
例如:
UserId Rolename
1 Admin
1 Editor
1 Other
2 Admin
3 Other
我想 return 每个用户包含 UserId, IsAdmin, IsEditor
的一行,其中后两列是表示用户是否具有 "Admin" 角色或 [=26] 的布尔值=]角色。
从上面的例子我会得到以下输出:
UserId IsAdmin IsEditor
1 True True
2 True False
3 False False
有什么想法吗?我一直在尝试各种具有分组依据、子选择等聚合函数的方法,但我就是不明白。
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
一种可能的解决方案:
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 设置多行。例如,用户 ID 1 在 table.
中两次具有 Admin
用户:
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
有几种方法可以做到这一点。假设您的 table 名为 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 到最新版本的任何地方工作。将 table 名称从 USERROLE 更改为您的 table 名称。
可以进行各种更改,但需要更多信息才能了解真正好的结构。
我有 table 个 UserId 和角色名。
例如:
UserId Rolename
1 Admin
1 Editor
1 Other
2 Admin
3 Other
我想 return 每个用户包含 UserId, IsAdmin, IsEditor
的一行,其中后两列是表示用户是否具有 "Admin" 角色或 [=26] 的布尔值=]角色。
从上面的例子我会得到以下输出:
UserId IsAdmin IsEditor
1 True True
2 True False
3 False False
有什么想法吗?我一直在尝试各种具有分组依据、子选择等聚合函数的方法,但我就是不明白。
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
一种可能的解决方案:
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 设置多行。例如,用户 ID 1 在 table.
中两次具有 Admin用户:
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
有几种方法可以做到这一点。假设您的 table 名为 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 到最新版本的任何地方工作。将 table 名称从 USERROLE 更改为您的 table 名称。
可以进行各种更改,但需要更多信息才能了解真正好的结构。