Sql 仅当另一个联接通过某些条件时,左联接表

Sql 仅当另一个联接通过某些条件时,左联接表,sql,join,left-join,ssms,Sql,Join,Left Join,Ssms,这是我一直遇到的SQL问题!(我使用SQLServer/SQLServerManagementStudio)我想左键联接一个表,但前提是它通过了需要另一个联接的测试。所以我要把B连接到A上,但我只想在B的连接到表C通过测试的情况下连接B 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.C

这是我一直遇到的SQL问题!(我使用SQLServer/SQLServerManagementStudio)我想左键联接一个表,但前提是它通过了需要另一个联接的测试。所以我要把B连接到A上,但我只想在B的连接到表C通过测试的情况下连接B

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。在我的标题中,我基本上想要左连接两个内部连接的表。。。“c.PassesTest上的左连接(b内部连接c)”基本上就是我想要做的

我的两个直接想法都失败了:
1.如果将PassesTest放入到C的连接中,(…在B.CID=C.CID和C.PassesTest上左连接C…)您仍然保留着所有不需要的B记录
2.如果您将测试放在where(如上所述),它会抛出所有未通过的A记录,但我需要这些记录(因为它是左连接)

我可以想出两种解决方案,但它们都有点痛苦。。。真的没有更简单的方法吗

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

  • 做一些嵌套选择。下面的方式似乎有点多余。。。也许可以写得好一点

    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问题?

    您的
    版本1
    不需要是一个子查询,您只需要
    ()
    围绕
    内部连接部分

    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
    子句放在
    内部连接
    谓词中


    另外,请注意,无论是在您的子查询版本中,还是在本例中,在将整个TableB连接到TableA之前,都不一定要将其连接到TableC


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

    太棒了!我不知道你能做到!非常感谢:)
    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