繁体   English   中英

sql从同一表和同一列中的值获取到一行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM