【问题标题】:Oracle left outer join, only want the null valuesOracle 左外连接,只需要空值
【发布时间】:2014-10-12 10:27:40
【问题描述】:

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

【问题讨论】:

  • 谢谢大家,看来问题已经解决了:)

标签: sql oracle join outer-join


【解决方案1】:

您可能想要明确选择空值:

 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】:

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

    【讨论】:

      【解决方案3】:

      看看这个网站,它对你很有帮助,所有连接语句的可视化说明和代码示例

      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

      【讨论】:

      • 请附上相关部分或链接文章内容的简要说明,以防链接失效。
      【解决方案4】:

      WHERE 子句过滤连接返回的数据。因此,当您的内部表包含特定列的空数据时,相应的行会根据您指定的条件被过滤掉。这就是为什么您应该将该逻辑移至 ON 子句。

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

      【讨论】:

      • 我希望可以添加索引,但是 SELECT 语句是我对数据库权限的限制。
      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 2010-09-26
        • 2016-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多