【问题标题】:Left Join table only if another join passes some criteria仅当另一个联接通过某些条件时才左联接表
【发布时间】:2013-07-11 21:02:30
【问题描述】:

这是我一直遇到的 SQL 问题! (我使用 Sql-Server/sql-management studio)我想离开加入一个表,但前提是它通过了需要另一个加入的测试。所以我将 B 加入 A 但我只想加入 B 如果 B 加入表 C 通过测试...

SELECT A.* 
FROM TableA A
LEFT JOIN TableB B on A.BID = B.BID  --only want to join B if C passes the test
LEFT JOIN TableC C on B.CID = C.CID
WHERE C.PassesTest -- not correct: throws out records from A that don't pass test

所以我只想在 C 通过测试时离开加入 B。正如我的标题,我基本上想左连接 2 个内连接的表......“C.PassesTest 上的左连接(b 内连接 c)”基本上是我想要做的。

我的 2 个直接想法都失败了:
1. 如果您将 PassesTest 放在与 C 的连接中,(... left join c on B.CID = C.CID AND C.PassesTest...)您仍然拥有所有您没有的 B 记录想。
2. 如果您将测试放在 where(如上),它会抛出所有未通过但我想要的 A 记录(因为它是左连接)。

我可以想到 2 个解决方案,但它们都有点麻烦……真的没有更简单的方法吗?

  1. 加入所有 B/C - 这在逻辑上是我想要的,但显然不是最优的,因为它在加入之前从 B 和 C 中获取所有内容(所以它很慢)

    SELECT A.* 
    FROM TableA A
    LEFT JOIN (
      SELECT * 
      FROM TableB B 
      INNER JOIN TableC C ON B.CID = C.CID 
      WHERE C.PassesTest
    ) BC ON BC.BID = A.BID
    
  2. 做一些嵌套选择。下面的方式好像有点多余……或许可以写得好一点

    SELECT ABC.StuffFromA FROM (
      SELECT * 
      FROM TableA A
      LEFT JOIN TableB B on A.BID = B.BID
      LEFT JOIN TableC C ON B.CID = C.CID 
    ) ABC
    LEFT JOIN TableB B on ABC.BID = B.BID AND ABC.PassesTest 
    

无论如何,这是我一直遇到的事情,我总是发现自己必须做一些非常困难的事情才能让它发挥作用!似乎应该有一个更简单的解决方案......或者这只是一个看似困难的 SQL 问题?

【问题讨论】:

    标签: sql join left-join ssms


    【解决方案1】:

    您的version 1 不需要是子查询,您只需要在INNER JOIN 部分周围使用()...

    SELECT
      A.* 
    FROM
      TableA A
    LEFT JOIN
      (
        TableB B 
      INNER JOIN
        TableC C
          ON  B.CID = C.CID 
          AND C.PassesTest
      )
        ON B.BID = A.BID
    

    我还将您所拥有的内容作为 WHERE 子句放入 INNER JOIN 谓词中。


    另外,请注意,无论是在您的子查询版本还是本示例中,整个 TableB 都必须在加入到 TableA 之前加入到 TableC。

    SQL 被编译成一个执行计划,优化器有很多选项可以防止这种情况发生。仅仅因为你这样写并不意味着 RDBMS 会盲目地遵循它而不进行优化。

    【讨论】:

    • 太棒了!我不知道你能做到这一点!非常感谢:)
    猜你喜欢
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2013-08-22
    • 2019-02-12
    相关资源
    最近更新 更多