SQL - 连续 "ON"语句

标签 sql sql-server tsql

当我在数据库的旧 View 中清理一些问题时,我遇到了这个“奇怪”的连接条件:

from
    tblEmails [e]
    join tblPersonEmails [pe]
        on (e.EmailID = pe.EmailID)
    right outer join tblUserAccounts [ua]
    join People [p]
        on (ua.PersonID = p.Id)
    join tblChainEmployees [ce]
        on (ua.PersonID = ce.PersonID)
        on (pe.PersonID = p.Id)

表 tblUserAccounts 被引用为右外连接,但直到引用 tblChainEmployees 之后才声明它的 on 条件;那么连续有两个连续的 on 语句。

我在互联网上的任何地方都找不到相关的答案,因为我不知道这种联接叫什么。

所以问题:
  • 这种“延迟条件”连接有名字吗?
  • 在 on 语句不连续的情况下,如何重写它以产生相同的结果集?
  • 当总是有更简单/更清晰的方法时,也许这是一个“聪明”的解决方案?
  • 最佳答案

    (1) 这只是语法,我从来没有听说过一些特殊的名字。如果您仔细阅读this MSDN article你会看到 (LEFT|RIGHT) JOIN必须与ON配对陈述。如果不是,里面的表达式被解析为 <table_source> .您可以添加括号以使其更具可读性:

    from
        tblEmails [e]
        join tblPersonEmails [pe]
            on (e.EmailID = pe.EmailID)
        right outer join
        (
            tblUserAccounts [ua]
            join People [p]
                on (ua.PersonID = p.Id)
            join tblChainEmployees [ce]
                on (ua.PersonID = ce.PersonID)
        ) on (pe.PersonID = p.Id)
    

    (2) 我更喜欢 LEFT语法,带有明确的括号(我知道,这是一个品味问题)。这会产生相同的执行计划:
    FROM tblUserAccounts ua
    JOIN People p ON ua.PersonID = p.Id
    JOIN tblChainEmployees ce ON ua.PersonID = ce.PersonID
    LEFT JOIN
    (
        tblEmails e
        JOIN tblPersonEmails pe ON e.EmailID = pe.EmailID
    ) ON pe.PersonID = p.Id
    

    (3) 是的,它很聪明,就像面试中的一些 C++ 表达式(即 (i++)*(*t)[0]<<p->a )一样。语言灵活。表达式和查询可能很棘手,但一些“安排”会导致可读性下降和错误。

    关于SQL - 连续 "ON"语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38796658/

    相关文章:

    sql - 从 SQL Server 检索任何外部表数据时,Postgresql 外部数据包装器引发错误

    sql - 如何按周选择总活跃列表数?

    c# - 使用 SMO 获取表默认值的创建脚本

    sql - 在 SQL 中处理多个硬编码值的最简单方法?

    oracle - 复杂的 SQL 查询

    tsql - SQL 查询中的多个计数

    mysql - 判断 MySQL COALESCE 从哪个表返回了值

    c# - 插入 Cast 数据和空字段 C# 时出错

    sql-server - 如何在 SQL Server 中使用 NOT IN 创建过滤索引

    python - pyodbc 无法连接到数据库