这是一个使用联合连接的查询,包含角色、权限表和其他一些中间表。我认为它有一些重复,我如何优化它,或者我可以换一种方式来写它?
SELECT DISTINCT
menu.perm_key
FROM
user_role
LEFT JOIN role ON user_role.role_id = role.id
LEFT JOIN role_menu ON user_role.role_id = role_menu.role_id
LEFT JOIN menu ON menu.id = role_menu.menu_id
WHERE
user_role.user_id = 1
AND role.`status` = 1
AND menu.`status` = 1
UNION
SELECT DISTINCT
role.role_key
FROM
user_role
LEFT JOIN role ON user_role.role_id = role.id
WHERE
user_role.user_id = 1
AND role.`status` = 1
下面是使用SELECT DISTINCT role_key, perm_key from ...
UPDATE:根据评论中的信息,我正在更新我的回复。
需要两列返回一列,我看到的唯一其他方法是使用某种函数。我在这里用IF
,但COALESCE
也可以工作。
SELECT DISTINCT
IF(menu.perm_key IS NOT NULL, menu.perm_key, role.role_key) as key
FROM
user_role
LEFT JOIN role ON user_role.role_id = role.id
LEFT JOIN role_menu ON user_role.role_id = role_menu.role_id
LEFT JOIN menu ON menu.id = role_menu.menu_id
WHERE
user_role.user_id = 1
AND role.`status` = 1
AND menu.`status` = 1
原始回答
如果没有更多的信息,我唯一看到的是UNION
似乎是不必要的。
SELECT DISTINCT
menu.perm_key, role.role_key
FROM
user_role
LEFT JOIN role ON user_role.role_id = role.id
LEFT JOIN role_menu ON user_role.role_id = role_menu.role_id
LEFT JOIN menu ON menu.id = role_menu.menu_id
WHERE
user_role.user_id = 1
AND role.`status` = 1
AND menu.`status` = 1
除非您希望这些值作为单独的行,否则应该可以正常工作。如果你期待分开排,我会问为什么。对我来说,每一行都应该代表"同样的东西"。和其他行一样,但是值不同。通过使用单独的行,一行表示"烫发键"。而下一个表示"角色键"。即使它们指向相同的对象类型或枚举,它们也有不同的用途,因此我将它们视为"不同的东西"。并且不适合返回单独的行。如果您的查询返回超过2行,这将是特别真实和尴尬的工作。