【问题标题】:two SQL tables with 2 columns in common, need records that are in table A but not in table B (column 1 is same in both but different column 2)两个共有 2 列的 SQL 表,需要在表 A 中但不在表 B 中的记录(第 1 列在两者中相同但第 2 列不同)
【发布时间】:2017-07-31 20:07:34
【问题描述】:

我有两个表,tableA 和 tableB。 它们都有列(vehicle_make 和 vehicle_model)。

我需要 tableA 中不存在于 tableB 中的所有车辆品牌/型号。

基本上我需要找到新的品牌和型号。 tableB 目前我在我的项目中使用,tableA 是美国所有车辆的通用数据。

【问题讨论】:

标签: sql oracle


【解决方案1】:

您可以使用NOT IN 运算符。

SELECT DISTINCT vehicle_make, vehicle_model
FROM tableA
WHERE (vehicle_make || vehicle_model) NOT IN 
      (SELECT DISTINCT (vehicle_make || vehicle_model)
       FROM tableB)

【讨论】:

  • 像这样连接vehicle_makevehicle_model 通常是个坏主意——它可能会导致误报。 'a' || 'bc' = 'ab' || 'c' 即使对 ('a', 'bc') 不匹配 ('ab', 'c')。立即回复(“但在这种情况下,这不太可能发生......”)也是不正确的 - 不应依赖数据的细节来证明可能存在错误的代码。更不用说,如果WHERE 子句(连接条件等)以这种方式编写,则无法使用所涉及列的索引。
  • 通常在连接中添加一个分隔符,以确保没有误报。无论如何我都会更新帖子。
  • 以这种方式使用的连接无论如何都是一个坏主意 - 有或没有“分隔符”。为什么不检查一个元组是否在一组元组中?这在 Oracle SQL 中确实有效(并且可能是标准的一部分)。
【解决方案2】:
select a.*
from TableA a
left outer join TableB b 
       on a.vehicle_make = b.vehicle_make 
      and a.vehicle_model = b.vehicle_model
where b.vehicle_make is null

【讨论】:

    【解决方案3】:

    使用协同子查询:通常是最有效的。

    SELECT vehicle_make, vehicle_model
    FROM tableA A
    WHERE Not Exists (SELECT * 
                      FROM tableB 
                      WHERE A.vehicle_make = B.Vehicle_make
                        and A.vehicle_model = B.Vehicle_model
    

    使用外连接(如果您需要表 B 中确实存在的记录的数据...例如 B 中每个品牌/型号的记录计数

    SELECT A.vehicle_make, A.vehicle_model, count(B.*)
    FROM tableA A
    LEFT JOIN tableB B
     on A.vehicle_make = B.Vehicle_make
    and A.vehicle_model = B.Vehicle_model
    WHERE B.Vehicle_make is null
    GROUP BY A.vehicle_make, A.vehicle_model
    

    In 有效(除非你可以有空值)

    【讨论】:

    • 相关子查询通常很慢,因为它们对来自tableA 的每一行计算一次(因为对于tableA 中的每一行,子查询不同)。幸运的是,Oracle 优化器通常足够聪明,可以使用NOT INNOT EXISTS 作为反连接来重写解决方案,从而使解决方案更快。至少从 Oracle 的最后两个或三个版本开始,NOT INNOT EXISTS 之间没有区别(由于优化器的改进)。
    • in vs 的“经验法则”存在:BIG 外部查询和 SMALL 内部查询 = IN。小外部查询和大内部查询 = WHERE EXISTS。请记住——这是一个经验法则,经验法则总是有无数个例​​外。 asktom.oracle.com/pls/asktom/…
    • 对 Oracle 8.1 正确答案的精彩参考! “至少从 Oracle 的最后两个或三个版本开始”我的意思是从 Oracle 10.1 左右开始。汤姆的答案是 100% 正确的 - 17 年前他写的时候。
    • 我喜欢你的山羊:P
    猜你喜欢
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    相关资源
    最近更新 更多