有两张桌子; X_User_Role 和角色就像这样
X_User_Role表:
df1 <- data.frame(variable_name = c(rep('var1', 3),rep('var2',4), rep('var3', 3), rep('var4', 4)),
var_value = c(1,4,2,4,3,6,2,1,6,3,1,3,2,4),
value_type = c('A','B','C','A','B','C','D','B','C','D','B','D','E','F'))
df2 <- data.frame( variable_name = c(rep('var6',4), rep('var4', 4)),
var_value = c(4,3,6,2,1,3,2,4),
value_type = c('A','B','C','D','B','D','E','F'))
ggplot() +
geom_col(data = df1,
aes(x = variable_name, y =var_value,fill = value_type),
width = 0.8)
ggplot() +
geom_col(data = df2,
aes(x = variable_name, y =var_value,fill = value_type),
width = 0.8)
角色表:
************************
UserRoleID UserID RoleID
************************
1 1 1
************************
2 1 2
************************
3 2 1
现在我正在编写带连接的select语句,这样在我的最终输出中它应该是(仅考虑1个用户ID):
********************************
RoleID Name SecondaryFl
********************************
1 PrimaryRole 0
********************************
2 SecondaryRole 1
********************************
我尝试过像这样加入:
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
我尝试了上述连接的不同变体,但我从未得到所需的输出。我无法弄清楚我做错了什么。我是SQL的新手。有人可以帮忙吗?
注意:我必须使用JOINS,因为这是一个更大的选择的一部分,它完全由JOINS组成。
答案 0 :(得分:4)
应使用条件聚合
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
列的值超出上述值,那么它将包含 null 总是行。
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;
答案 1 :(得分:1)
我认为这个问题缺少一些事实。比如,哪个角色有资格成为次要角色?但是对于这个答案,我将假设SecondaryFl
字段表明了这一点。 0表示主要,1表示次要。
我相信您遇到的问题是由于您的查询:
JOIN Role r2
ON r2.RoleID = r1.RoleID AND SecondaryFl = 1
由于您是第二次在同一主键上加入Role表。相反,你想再次加入它,但它有自己的条件。
像这样:
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')
的方法处理返回的空值,或者只是将返回的空值视为接收结果的位置。
像这样:
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
答案 2 :(得分:1)
您可以使用如下所示的数据透视查询 的 see live demo 强>
在你的笔记上:
我必须使用JOINS,因为这是一个更大的选择的一部分,它完全由JOINS组成。
您始终可以在查询中将其封装为JOIN中的嵌套查询
,
如果您绝对需要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
答案 3 :(得分:0)
返回动态数量的列?你正在寻找麻烦。
您应该返回角色,每行一个。一个简单的SQL连接就可以了。
答案 4 :(得分:0)
这是我在评论中提出的建议:
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
答案 5 :(得分:0)
只是想发布另一个不诉诸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