[英]sql getting values from the same table and same column into one row
有两个表; X_User_Role和这样的角色
X_User_Role表:
************************
UserRoleID UserID RoleID
************************
1 1 1
************************
2 1 2
************************
3 2 1
角色表:
********************************
RoleID Name SecondaryFl
********************************
1 PrimaryRole 0
********************************
2 SecondaryRole 1
********************************
现在,我正在编写一个带有连接的select语句,以便在我的最终输出中它应该为(仅考虑1个用户ID):
UserID PrimaryRoleName SecondaryRoleName
***********************************************************
1 PrimaryRole SecondaryRole
我试过像这样加入:
select xur.UserID, r1.Name as PrimaryRoleName, r2.Name as SecondaryRoleName
from X_User_Role xur
JOIN Role r1
ON r1.RoleID = xur.RoleID
JOIN Role r2
ON r2.RoleID = r1.RoleID AND SecondaryFl = 1
但是我总是得到这样的输出:
UserID PrimaryRoleName SecondaryRoleName
***********************************************************
1 PrimaryRole PrimaryRole
我尝试了上述联接的不同变体,但从未获得所需的输出。 我无法弄清楚我在做什么错。 我是SQL的完全新手。 谁能帮忙吗?
注意:我必须使用JOINS,因为这是较大选择的一部分,后者完全由JOINS组成。
应该使用条件聚合
select xur.userId,
max(case when SecondaryFl = 0 then r.name end) as PrimaryRoleName,
max(case when SecondaryFl = 1 then r.name end) as SecondaryRoleName
from X_User_Role xur
join Role r on r.RoleID = xur.RoleID
group by xur.userId;
由(YogeshSharma)编辑
在进行条件聚合时,始终包含where
子句,因为如果SecondaryFl
列的值大于上述值,那么它将始终包含空行。
select xur.userId,
max(case when SecondaryFl = 0 then r.name end) as PrimaryRoleName,
max(case when SecondaryFl = 1 then r.name end) as SecondaryRoleName
from X_User_Role xur
join Role r on r.RoleID = xur.RoleID
where SecondaryFl in (1, 0) -- Always include especially for conditions aggregation
group by xur.userId;
我认为这个问题缺少一些事实。 像是,什么才能使角色成为继任者和主要角色? 但是对于这个答案,我将假设SecondaryFl
字段指示了这一点。 0代表小学,1代表中学。
我相信您看到的问题是由于您的查询导致的:
JOIN Role r2
ON r2.RoleID = r1.RoleID AND SecondaryFl = 1
由于您是第二次加入角色表,因此要使用相同的主键。 相反,您希望再次加入它,但要有自己的条件。
像这样:
select
user_role.UserID,
role_primary.Name as PrimaryRoleName,
role_secondary.Name as SecondaryRoleName
from X_User_Role as user_role
join Role as role_primary
on role_primary.RoleID = user_role.RoleID and SecondaryFl = 0
join Role as role_secondary
on role_secondary.RoleID = user_role.RoleID and SecondaryFl = 1
抱歉,我更改了您的名字,我觉得它更易读。 我认为这应该可以更清楚地说明这一点。
编辑:我认为角色将始终在这里。 如果角色是可选的,则可以改用left join
,并使用coalesce(role_primary.Name, 'None')
处理返回的null,或者仅在接收结果的地方处理返回的null。
像这样:
select
user_role.UserID,
coalesce(role_primary.Name, 'None') as PrimaryRoleName,
coalesce(role_secondary.Name, 'None') as SecondaryRoleName
from X_User_Role as user_role
left join Role as role_primary
on role_primary.RoleID = user_role.RoleID and SecondaryFl = 0
left join Role as role_secondary
on role_secondary.RoleID = user_role.RoleID and SecondaryFl = 1
您可以使用如下所示的数据透视查询查看实时演示
在您的笔记上:
我必须使用JOINS,因为这是完全由JOINS组成的更大选择的一部分。
您可以始终将下面的查询封装为JOIN中的嵌套查询
select
UserId,
PrimaryRoleName=[0],
SecondaryRoleName=[1]
from
(
select
X.UserID,
Name,
SecondaryFl
from
X_User_Role X
left join Role R
on X.RoleID=R.RoleID
) src
pivot
(
max(Name) for SecondaryFl in ([0],[1])
)p
如果您绝对希望使用JOIN语法,可以尝试以下查询
select
UserID=X.UserID,
PrimaryRoleName=MAX(case when SecondaryFl=0 then Name else NULL end),
SecondaryRoleName=MAX(case when SecondaryFl=1 then Name else NULL end)
from
X_User_Role X
left join Role R
on X.RoleID=R.RoleID
group by X.UserID
返回动态列数? 您正在寻找麻烦。
您应该返回角色,每行一个。 一个简单的SQL连接即可。
这是我在评论中建议的内容:
select xur.UserID, r1.Name as PrimaryRoleName, r2.Name as SecondaryRoleName
from X_User_Role xur
JOIN Role r1
ON r1.RoleID = xur.RoleID AND r1.SecondaryFl <> 1
JOIN Role r2
ON r2.RoleID = xur.RoleID AND r2.SecondaryFl = 1
WHERE xur.UserID=1
只是想发布另一个求助于GROUP BY
答案:
select x1.userid, r1.name, r2.name
from x_user_role x1, role r1, x_user_role x2, role r2
where r1.roleid = x1.roleid and r1.secondaryfl = 0
and x1.userid = 1
and r2.roleid = x2.roleid and r2.secondaryfl = 1
and x2.userid = x1.userid
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.