使用 JOIN 与 IN/NOT IN 以提高可读性

Posted

技术标签:

【中文标题】使用 JOIN 与 IN/NOT IN 以提高可读性【英文标题】:Usage of JOINs vs IN/NOT IN for readability 【发布时间】:2015-12-02 15:28:49 【问题描述】:

让我先说这不是关于效率的问题。

假设,为了争论,我有一个包含两个表的数据库:用户和角色。

用户看起来像这样:

Username    Password    FirstName    LastName
--------    --------    ----------   ---------
braab       pass1234    Braab        Himself
joe         pass1257    Joe          Smith
robert      pass1235    Robert       Irvine
kelly       pass1236    Kelly        Clarkson

角色如下所示:

Username    Role
--------    ----
braab       admin
robert      customer
kelly       developer
joe         admin

我想查找所有具有“管理员”角色的用户的名字和姓氏。

我有两种方法来实现这一点:使用连接或使用 in 子句。

输入方法:

select
    firstname, lastname
from
    users
where
    username in
        (select
             username
         from
             roles
         where
             role = 'admin' 
        )

加入方法:

select
    user.firstname, user.lastname
from
    users as user
inner join
    roles as role
on
    user.username = role.username

哪种方法更清楚我正在尝试查找管理员用户的名字和姓氏?有预期用途吗?对我来说,in 子句是实现上述目标的最明确的方式。

根据您对 SQL 的经验/培训,我可以看到这两种方式。我担心的是我希望其他开发人员能够理解我想要实现的目标。

【问题讨论】:

请注意,当子查询可以返回 NULL 时,NOT IN 可能会很棘手。我会使用JOIN 而不是IN/NOT IN,尤其是当子查询相关时。 一个用户可以有多个角色吗?否则最好在Users 表上添加一个字段 这两个语句不一定返回相同的东西,例如当一个用户可以拥有多个角色时 您的 JOIN 示例缺少 where role.Role = 'admin'。至于问题:总是加入。如果您有两个以上的表,则子查询的可读性会降低。此外,效率应该对您很重要。 不能同时理解它们的人不是开发者。 【参考方案1】:

问题不在于开发人员是否能够理解代码。您应该专注于能够提供最佳性能的内容。

正如您在这个 SQL Fiddle Demo 中看到的那样,执行计划是不同的。处理哪些表的顺序不同。因为表是小索引不会成为一个因素,但这也会影响你使用什么选项。

【讨论】:

这是个问题。如果另一个开发人员必须维护我的代码,那么他们了解我在做什么很重要。性能很重要,但可读性也很重要。 *** 已经被效率问题所淹没。我想知道上面两个查询中哪一个最清楚地实现了示例中的目标。 @braab 都同样清楚,所以更像你遵循的标准。我喜欢使用更多的JOIN 而不是IN。因为代码行更少。【参考方案2】:

FWIW,这将是我的选择。简洁易读的代码,并为不想阅读代码的人提供注释。

-- get first and last name of all users who have the 'admin' role
SELECT users.firstname
     , users.lastname
FROM users
INNER JOIN roles
    ON users.username = roles.username
WHERE roles.Role = 'admin'

正如我在评论中所写,一旦超过 2 个或 3 个表,JOIN 在可读性方面比 IN 子查询要好得多。

【讨论】:

以上是关于使用 JOIN 与 IN/NOT IN 以提高可读性的主要内容,如果未能解决你的问题,请参考以下文章

为什么 EXISTS(NOT EXIST) 与 JOIN(LEFT JOIN) 的性能会比 IN(NOT IN) 好

字符串与字符 in --- not in

SQL in/not in/exists/not exists

oracle中in,not in和exists,not exists之间的区别

python列表的 + * in not in len() max() min()

mybatis sql in not in的使用