将同一表和同一列中的值放入一行的sql
有两张桌子;X_用户_角色和这样的角色 X_用户_角色表:将同一表和同一列中的值放入一行的sql,sql,sql-server,join,Sql,Sql Server,Join,有两张桌子;X_用户_角色和这样的角色 X_用户_角色表: ************************ UserRoleID UserID RoleID ************************ 1 1 1 ************************ 2 1 2 ************************ 3 2 1 *******************************
************************
UserRoleID UserID RoleID
************************
1 1 1
************************
2 1 2
************************
3 2 1
********************************
RoleID Name SecondaryFl
********************************
1 PrimaryRole 0
********************************
2 SecondaryRole 1
********************************
角色表:
************************
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
但我总是得到这样的输出:
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的新手。有人能帮忙吗
注意:我必须使用联接,因为这是完全由联接组成的较大选择的一部分。应使用条件聚合
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;
约格沙玛编辑
在执行条件聚合时始终包含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;
应使用条件聚合
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;
约格沙玛编辑
在执行条件聚合时始终包含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;
返回动态列数?你在找麻烦 如果用户有三个、四个、五个角色呢?
您应该返回角色,每行一个。一个简单的SQL连接就可以了。返回动态的列数?你在找麻烦 如果用户有三个、四个、五个角色呢?
您应该返回角色,每行一个。一个简单的SQL连接就可以了。我认为这个问题缺少一些事实。比如,什么使一个角色成为次要角色和主要角色?但对于这个答案,我将假设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
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
很抱歉我改了你的名字,我只是觉得它更易读。我认为这应该更清楚地说明这一点
编辑:我假设角色总是出现在这里。如果角色是可选的,则可以使用左连接,并使用类似于coalescerole_primary.Name的“None”来处理返回的null,或者只在接收结果的地方处理返回的null
像这样:
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
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
我认为这个问题缺少一些事实。比如,什么使一个角色成为次要角色和主要角色?但对于这个答案,我将假设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
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
很抱歉我改了你的名字,我只是觉得它更易读。我认为这应该更清楚地说明这一点
编辑:我假设角色总是出现在这里。如果角色是可选的,则可以使用左连接,并使用类似于coalescerole_primary.Name的“None”来处理返回的null,或者只在接收结果的地方处理返回的null
像这样:
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
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
您可以使用如下所示的透视查询 请注意: 我必须使用连接,因为这是完全由连接组成的更大选择的一部分 您始终可以将下面的查询封装为联接中的嵌套查询
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
如果您确实需要联接语法,可以尝试下面的查询
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
您可以使用如下所示的透视查询 请注意: 我必须使用连接,因为这是完全由连接组成的更大选择的一部分 您始终可以将下面的查询封装为联接中的嵌套查询
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
如果您确实需要联接语法,可以尝试下面的查询
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
这就是我在评论中的建议:
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
这就是我在评论中的建议:
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:
只是想发布另一个答案,而不是求助于GROUP BY:
您不认为您可能需要在第一次加入时指定第二个FL 1吗?然后第二次加入xur表,而不是r1I,我也试过了。在这种情况下,我得到的主要角色和次要角色的值仅为“Primary”,我不确定您到底尝试了什么,但如果您确实尝试了我建议的方法,它会起作用。选择xur.UserID,r1.Name作为PrimaryRoleName,r2.Name as SecondaryRoleName from X_User_Role xur JOIN Role r1 ON r1.RoleID=xur.RoleID和SecondaryFl=0 JOIN Role r2 ON r2.RoleID=xur.RoleIDI如上所述尝试过,但得到的主次值都是primary,您不认为可能需要在第一次连接时指定SecondaryFl 1吗?妈妈呢
让您第二次加入xur表,而不是r1I,我也尝试过。在这种情况下,我得到的主要角色和次要角色的值仅为“Primary”,我不确定您到底尝试了什么,但如果您确实尝试了我建议的方法,它会起作用。选择xur.UserID,r1.Name作为PrimaryRoleName,r2.Name作为SecondaryRoleName来自X_User_Role xur JOIN Role r1上的r1.RoleID=xur.RoleID和SecondaryFl=0 JOIN Role r2.RoleID=xur.RoleIDI像上面一样尝试过,但得到的主次值都是primaryYeah,但此查询不适用于两个以上的角色。我真的认为这家伙应该重新考虑他想要的结果。是的,但这个查询不适用于两个以上的角色。我真的认为这家伙应该重新考虑他想要的结果。每个用户只有两个角色。他可能有主列、次列或者两者都有。为什么你认为OP需要动态的列数?这个问题显然需要两个角色,每个用户只有两个角色。他可能有主列、次列或者两者都有。为什么你认为OP需要动态的列数?这个问题显然有两个问题。