SQL全外连接排除,选择不存在的行

时间:2013-02-06 15:28:55

标签: sql join left-join outer-join

这对我来说是一个令人困惑的问题。

我有3张桌子

section
id
name

permission
id
section_id
name

exclusion_permission
permission_id

查询如下:

SELECT
    p.id AS permission_id,
    p.name AS permission_name,
    s.id AS section_id,
    s.name AS section_name
FROM
    section s

LEFT OUTER JOIN
    permission p
ON
    p.section_id = s.id

LEFT OUTER JOIN
    exclusion_permission lep
ON
    lep.permission_id = p.id

WHERE
    lep.permission_id IS NULL

表数据是:

section
id     name
1      admin
2      sales
3      moderator
4      intern

permission
id     section_id    name
1      1             root
2      2             sell
3      2             buy
4      3             edit_user
5      3             delete_user

查询将返回

1, root, 1, admin
2, sell, 2, sales
3, buy, 2, sales
4, edit_user, 3, moderator
5, delete_user, 3, moderator
,, 4, intern

现在,如果我将以下排除权限投入混合:

exclusion_permission
permission_id
1
5

查询将返回:

2, sell, 2, sales
3, buy, 2, sales
4, edit_user, 3, moderator
,, 4, intern

正如您所看到的,主持人部分仍然存在,因为它还有一行与之关联。但是管理员部分已被删除,因为它与之关联的唯一权限已被排除。我想要做的是让我的查询返回以下内容:

,, 1, admin
2, sell, 2, sales
3, buy, 2, sales
4, edit_user, 3, moderator
,, 4, intern

因此,如果该部分没有权限,请显示该部分。此外,如果某个部分具有全部排除的权限,则仍会显示该部分没有相关权限。

我该怎么做?感谢

2 个答案:

答案 0 :(得分:0)

更改联接的顺序,只有在找不到permission时才加入exclusion_permission

SELECT
    p.id AS permission_id,
    p.name AS permission_name,
    s.id AS section_id,
    s.name AS section_name
FROM
    section s
LEFT OUTER JOIN
    exclusion_permission lep
ON
    lep.permission_id = s.id
LEFT OUTER JOIN
    permission p
ON
    p.section_id = s.id
    AND lep.permission_id IS NULL

Working example at SQL Fiddle.

答案 1 :(得分:0)

使用UNION添加这些记录:

...
UNION
SELECT NULL,
       NULL,
       id,
       name
FROM section
WHERE id NOT IN (SELECT section_id
                 FROM permission
                 WHERE id NOT IN (SELECT permission_id
                                  FROM exclusion_permission))

SQL Fiddle