【问题标题】:SQL - one-to-many and get all users that don't haveSQL - 一对多并获取所有没有的用户
【发布时间】:2018-08-25 13:53:36
【问题描述】:

我有用户和权限表。它们之间的关系是:

一个用户HAS MANY 权限。

我需要获取所有没有hide权限的用户。

例如,users 表有:

 id ¦ name   ¦ email           ¦ password  
 ---+ -------+-----------------+---------- 
  1 ¦ Test 1 ¦ test@gmail.com  ¦ 1234      
  2 ¦ Test 2 ¦ test2@gmail.com ¦ 2345      
  3 ¦ Test 3 ¦ test3@gmail.com ¦ 2345  
  4 ¦ Test 4 ¦ test4@gmail.com ¦ 8888
  5 ¦ Test 5 ¦ test5@gmail.com ¦ 9876  

权限表如下:

   user_id ¦ permission  
  ---------+------------ 
   1       ¦ read        
   2       ¦ edit        
   2       ¦ hide     
   4       ¦ edit   
   5       ¦ hide        

这是我迄今为止尝试过的:

SELECT * 
FROM users 
  LEFT JOIN permissions 
         ON users.id = permissions.user_id 
        AND permissions.permission != 'hide'

但这仍然让我获得第二个用户,因为第二个用户也有权限编辑。

预期结果:

 id ¦ name   ¦ email           ¦ password  ¦ permission 
 ---+ -------+-----------------+---------- +------------
  1 ¦ Test 1 ¦ test@gmail.com  ¦ 1234      ¦ read      
  3 ¦ Test 3 ¦ test3@gmail.com ¦ 2345      ¦ null      
  4 ¦ Test 4 ¦ test4@gmail.com ¦ 8888      ¦ edit         

这里最好的方法是什么?

【问题讨论】:

  • users 表的示例数据没有 id 列,但查询使用该列...
  • 再添加几行样本数据,同时指定预期的结果。

标签: sql join


【解决方案1】:

not exists 的好案例

SELECT * 
FROM users u
left JOIN permissions p
  ON u.id = p.user_id 
where not exists ( select 1 
                   from permissions p2
                   where p2.user_id = u.id 
                   and p2.permission = 'hide'
                 )

【讨论】:

    【解决方案2】:
    SELECT * 
    FROM users u
    left JOIN permissions p
      ON u.id = p.id 
    where u.id not in 
    ( 
      select id
      from permissions
      where permission = 'hide'
      group by id
    )
    

    输出

    id  Name    Email   Password        id       permission
    1   Test 1  test@gmail.com  1234    1        read
    3   Test 3  test3@gmail.com 2345    (null)   (null)
    

    【讨论】:

    • 请提供解释。应避免仅使用代码回答。
    • 不,这并没有给出你提供的输出,我仍然看到所有用户,但是对于具有权限hide的用户,我看到权限null
    • 然后使用WHERE permission IS NOT NULL过滤
    【解决方案3】:

    一个可能的答案可能是

    select * from Users U
    inner join Permissions P on P.id=U.id 
    WHere U.id NOT IN (SELECT U.ID FROM  Users U
    inner join Permissions P on P.id=U.id 
    WHere P.Permission ='HIDE')
    

    1) 这将返回具有隐藏权限的 ID

    SELECT U.ID FROM  Users U
    inner join Permissions P on P.id=U.id 
    WHere P.Permission ='HIDE'
    

    2)这将返回除上述返回的 id 之外的所有数据,这将是您的预期

    select * from Users U
    inner join Permissions P on P.id=U.id 
    WHere  U.id NOT IN (SELECT U.ID FROM  Users U
    inner join Permissions P on P.id=U.id 
    WHere P.Permission ='HIDE')
    

    【讨论】:

    • 这个,和之前cmet中的解决方案类似,只会返回有一定权限的用户,但我也需要没有任何权限的用户。
    猜你喜欢
    • 1970-01-01
    • 2011-04-21
    • 2023-02-23
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多