Oracle左外连接,只想要空值

我正在研究两个表的问题 . 充电和充电历史 . 我想显示两个表中的列的选择,其中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)

2 years ago

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

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

2 years ago

您可以在 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.valueleft outer join 更改为 inner join ,因为 NULL 结果将被过滤掉 .

2 years ago

看看这个网站,它将对您非常有帮助,所有连接语句的可视化插图与代码示例

blog.codinghorror.com

Quoted of the relevant info in the above link:

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

Sample output:

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

Left outer join

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

2 years ago

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

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

2 years ago

对于 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使用的相同查询结构,所以请将此视为支持 .