【问题标题】:How do I get all records from tableA with a left outer join and a where condition on tableB?如何使用左外连接和 tableB 上的 where 条件从 tableA 获取所有记录?
【发布时间】:2009-09-29 02:05:48
【问题描述】:

基本上,我想要的是如果 tableB 中有类型为“X”的记录,我想查看它,否则我不想要,但我想要 tableA 中的所有记录。

我知道我可以通过将 tableB.type = 'X' 放在 LEFT OUTER JOIN ON 子句中来完成此操作,但我不能这样做,因为我仅限于使用 where 条件,因为我正在使用我不会命名的程序的受限查询管理器,但我绝对讨厌。 :)

SELECT *
FROM tableA 
LEFT OUTER JOIN ON tableA.ID = tableB.ID
WHERE tableB.type = 'X'

我该如何做到这一点?

编辑

我已经尝试过了,但我仍然没有从 tableA 中获取所有记录。我正在 SQL 服务器上对此进行测试,以避免长时间等待我的查询在生产系统上运行。如果有帮助的话,我很确定生产系统正在使用 Oracle。

SELECT *
FROM tableA LEFT OUTER JOIN ON tableA.ID = tableB.ID
WHERE tableB.type = 'X' OR tableB.type IS NULL

【问题讨论】:

    标签: sql


    【解决方案1】:

    检查表 B 中的nulls:

    SELECT *
    FROM tableA LEFT OUTER JOIN ON tableA.ID = tableB.ID
    WHERE tableB.type = 'X'
    OR tableB.type IS NULL
    

    这将在连接匹配时从两个表中获取所有内容,当 tableB 中没有相应记录时从 tableA 中获取所有内容。

    如果type 可以自然地成为null,你会想要将条件更改为更合理的:

    SELECT *
    FROM tableA LEFT OUTER JOIN ON tableA.ID = tableB.ID
    WHERE tableB.type = 'X'
    OR tableB.ID IS NULL
    

    假设ID是主键,自然不能是null,结果是一样的。

    【讨论】:

    • 在这些情况下,我总是尝试将主键与“IS NULL”进行比较——这是此答案中的第二个 SQL sn-p。
    • 这在 SQL Server 中不起作用。引用 tableb 的 where 子句将内部连接更改为内部连接。当我添加 where 子句时,它只给我带来了我正在查看的字段中为 null 的记录。如果我把它放在 ID 字段上,我仍然得到错误的答案
    【解决方案2】:

    不知道您是否有权访问数据库,或者是否由于其他限制而必须专门查询 tableB,但您始终可以创建一个名为 tableBTypeX 的表 b 的视图,其中该视图仅限于那些行类型 = x。然后你可以针对 tableBTypeX 离开外连接。在您的查询中,连接列是 ID 列,因此它们可能具有索引,从而使查询在速度方面很好。在连接列没有索引的情况下,连接视图会更有效,因为连接的行更少,连接未索引的行通常需要全表扫描,这使得查询更加耗时。

    【讨论】:

    • 您可以使用内联视图,而不是完整的视图。
    【解决方案3】:

    您可以通过修改连接条件来专门连接表B中的“类型X”记录:

    SELECT 
      *
    FROM 
      tableA 
      LEFT OUTER JOIN ON 
        tableA.ID = tableB.ID  
        AND tableB.type = 'X'
    

    【讨论】:

    • 他特别说不能在ON子句里做,必须在WHERE子句里做。
    • OP 提到他不能修改 join 语句。
    【解决方案4】:

    UNION 可能吗?

    SELECT *
    FROM tableA 
    LEFT OUTER JOIN ON tableA.ID = tableB.ID
    WHERE tableB.type = 'X'
    
    UNION
    
    SELECT *
    FROM tableA 
    

    ... 还是 CTE?不确定名称 tableB 将如何解析并且无法测试...

    ;WITH tableB AS
    (
        SELECT * FROM tableB WHERE type = 'X'
    )
    SELECT *
    FROM
        tableA 
        LEFT OUTER JOIN
        tableB ON tableA.ID = tableB.ID
    

    【讨论】:

      猜你喜欢
      • 2012-08-14
      • 2017-11-18
      • 1970-01-01
      • 2017-11-09
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多