Oracle左外连接,只想要空值

时间:2014-08-19 10:45:05

标签: sql oracle join outer-join

我正在处理两个表的问题。充电和充电历史。我想显示两个表中的列的选择,其中ChargeHistory中的匹配行具有与Charge不同的值和/或日期,或者如果ChargeHistory中根本没有匹配的条目。

我使用了使用ansi标准声明的左外连接,虽然它确实显示了正确的行,但它没有显示空条目。

我已经读过,如果您使用WHERE子句以及ON子句,有时会出现问题。但是,当我尝试将所有条件放在ON子句中时,查询花费的时间太长> 15分钟(这么长时间我刚刚取消了跑步)。

更糟糕的是,两个表都使用三部分复合键。

有没有人想到为什么遗漏空值?

    SELECT values...
    FROM bcharge charge
    LEFT OUTER JOIN chgHist history
    ON charge.key1 = history.key1 AND charge.key2 = history.key2 AND charge.key3 = history.key3 AND charge.chargeType = history.chargeType
    WHERE charge.chargeType = '2'
      AND (charge.value <> history.value OR charge.date <> history.date)
    ORDER BY key1, key2, key

5 个答案:

答案 0 :(得分:2)

您可能希望显式选择空值:

 SELECT values...
    FROM bcharge charge
    LEFT OUTER JOIN chgHist history
    ON charge.key1 = history.key1 AND charge.key2 = history.key2 AND charge.key3 = history.key3 AND charge.chargeType = history.chargeType
    WHERE charge.chargeType = '2'
      AND ((charge.value <> history.value or history.value is null) OR (charge.date <> history.date or history.date is null))
    ORDER BY key1, key2, key

答案 1 :(得分:1)

您可以在where中明确查找匹配项。我建议查看用于join的其中一个键:

SELECT . . . 
FROM bcharge charge LEFT OUTER JOIN
     chgHist history
     ON charge.key1 = history.key1 AND charge.key2 = history.key2 AND
        charge.key3 = history.key3 AND charge.chargeType = history.chargeType
WHERE charge.chargeType = '2' AND
      (charge.value <> history.value OR charge.date <> history.date OR history.key1 is null)
ORDER BY key1, key2, key;

表达式charge.value <> history.value会将left outer join更改为inner join,因为NULL结果会被过滤掉。

答案 2 :(得分:1)

看一下这个网站,它对你很有帮助,用代码示例对所有连接语句进行直观说明

blog.codinghorror.com

引用上述链接中的相关信息:

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name

示例输出:

id  name       id    name
--  ----       --    ----
1   Pirate     2     Pirate
2   Monkey     null  null
3   Ninja      4     Ninja
4   Spaghetti  null  null

左外连接

从表A中生成一组完整的记录,其中包含表B中的匹配记录(如果可用)。如果没有匹配,则右侧将包含null

答案 3 :(得分:0)

WHERE子句过滤连接返回的数据。因此,当您的内部表具有特定列的空数据时,相应的行将根据您指定的条件进行过滤。这就是为什么你应该将该逻辑转移到ON子句。

对于性能问题,您可以考虑在用于加入和过滤的列上添加索引。

答案 4 :(得分:0)

对于where clause中使用的外连接表中的任何字段,您还必须为该相同字段允许IS NULL选项,否则您将否定外连接的效果,结果是相同的好像你曾经使用过内部联接。

SELECT
      *
FROM bcharge charge
      LEFT OUTER JOIN chgHist history
                  ON charge.key1 = history.key1
                        AND charge.key2 = history.key2
                        AND charge.key3 = history.key3
                        AND charge.chargeType = history.chargeType
WHERE charge.chargeType = '2'
      AND (
            (charge.value <> history.value OR history.value IS NULL)
           OR 
            (charge.date <> history.date OR history.date IS NULL)
          )
ORDER BY
      key1, key2, key3

编辑:看来这与上面的Rene使用的查询结构相同,所以请将此处理为支持请求。