带有加入条件的 SQL 请求

Posted

技术标签:

【中文标题】带有加入条件的 SQL 请求【英文标题】:SQL request with a joining condition 【发布时间】:2019-02-18 14:12:58 【问题描述】:
SELECT mairie.city, permission.permission
    FROM permission , user_mairie, mairie
    WHERE user_mairie.iduser = 1
    AND user_mairie.idmairie = mairie.idmairie
    CASE user_mairie.idrole
        WHEN 2 THEN 
            JOIN user_permission 
              ON user_permission.idpermission = permission.idpermission 
             AND user_permission.iduser = user_mairie.iduser
    END
    ORDER BY mairie.idmairie, permission.idpermission

如果该用户具有特定角色,我正在尝试获取该用户的权限。

“mairie”在法语中是“市政厅”。

一个用户可以在不同的“mairie”中扮演不同的角色。

如果user_mairie 上的用户idrole = 2,那么我们必须去表“user_permission”获取它的权限。

如果user_mairie 上的用户idrole = 1,那么他是admin,拥有ALL 权限,但是权限没有写在user_permission 中(因为user_permission 只用于idrole = 2)。

我想要的是例如:

如果 user_mairie.idrole = 1:

SELECT * 
FROM permission

如果 user_mairie.idrole = 2

SELECT * 
FROM permission, user_permission 
WHERE user_mairie.idrole = 2 
AND user_mairie.iduser = user_permission.iduser
AND user_permission.idpermission = permission.idpermission

我可以使用我的编程语言并发出 2 个请求来做到这一点,但我想知道在纯 SQL 中是否可以解决此问题。

一些数据:

表权限:

idpermission | permission
1            | permission_1
2            | permission_2
3            | permission_3

表 user_mairie:

iduser     | idmairie    | idrole
1          | 1           | 1
1          | 2           | 2

表用户权限:

iduser     | idpermission  | idmairie
1          | 1             | 2
1          | 3             | 2

餐桌主人:

idmarie     | city
1           | mairie_1
2           | mairie_2

我想要的结果(对于给定的 iduser = 1)将是:

mairie_1 : permission_1, permission_2, permission_3
mairie_2 : permission_1, permission_3

感谢您阅读我。

【问题讨论】:

这些是完全不同的查询,可能无法将它们组合成一个逻辑查询。 FROM permission , user_mairie, mairie carthesians join 已被弃用大约 25 年。考虑使用JOIN 今日提示:始终使用现代、明确的JOIN 语法。更容易编写(没有错误),更容易阅读和维护,如果需要更容易转换为外连接! 永远不要使用SELECT * @jarlh 和 cid :好的,我从现在开始尝试使用 JOIN,但我有坏习惯 【参考方案1】:

SQL DEMO

首先,您从所有 marie 和所有权限开始

 SELECT um.idrole, m.city, p.permission
 FROM user_mairie um
 JOIN mairie m 
   ON um.idmairie = m.idmairie
 CROSS JOIN permission p 
 WHERE um.iduser = 1

现在你删除你没有的权限

 WHERE um.iduser = 1
   AND (    um.idrole = 1 -- have all permission
         OR EXISTS (SELECT up.idpermission
                    FROM user_permission up
                    WHERE up.iduser = um.iduser 
                      AND up.idpermission = p.idpermission )
       )

输出

【讨论】:

您好,谢谢您的回答。事实上,如果idrole = 1,我需要所有权限才能被选中 你在哪里有所有权限的列表? 在表权限 我认为是时候添加一些示例数据和预期输出了。 我最后想要的是: - mairie.city 的列表:[idrole = 1 时的所有权限,idrole = 2 时只有 user_permission] - 其他 mairie.city ...【参考方案2】:

我想你真的很想要LEFT JOIN:

SELECT . . .
FROM user_mairie LEFT um
     user_permission up
     ON um.iduser = up.iduser LEFT JOIN
     permission p
     ON up.idpermission = p.idpermission OR
        um.idrole = 1 ;

您可能不希望idrole 的条件。

这仅获得 id 角色“2”的权限。

注意事项:

SELECT 中列出您想要的所有列。 学习使用正确、明确、标准 JOIN 语法。切勿在 FROM 子句中使用逗号。 表别名使查询更易于编写和阅读。 使用LEFT JOIN,这样即使没有权限,您也可以保留所有行。

【讨论】:

据我了解,idrole = 2 的用户的 user_permission 表中没有记录 @Jimmmy 这是相反的,但你明白了! idrole = 1 的用户的 user_permission 中没有记录! 感谢您的询问,但我不明白如何在不将其添加到 FROM 中的情况下获得 permission.permission(而 permission.permission 是我想要的) @shqnks 。 . .嗯? permissionFROM 子句中。只需将其添加到SELECT 好的,我试试,但是如果 um.idrole = 1 我需要所有权限,如果 um.idrole = 2 我需要查看 user_permission 表以查看用户的权限有。我不知道我是否可以理解对不起

以上是关于带有加入条件的 SQL 请求的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server - 内部加入 - 条件语句

EF Core/SQL 根据条件加入不同的实体

条件连接 | SQL |优化性能并减少数量。加入数

如何在 SQL 中使用条件逻辑来选择要加入的记录?

“java.sql.SQLSyntaxErrorException:'on 子句'中的未知列'*'”在休眠条件下加入表时

有条件地加入 - COALESCE 与 OR - Oracle SQL