在 SQL 中查找表之间缺失的数字
Posted
技术标签:
【中文标题】在 SQL 中查找表之间缺失的数字【英文标题】:Finding missing number between tables in SQL 【发布时间】:2009-09-11 06:34:18 【问题描述】:我正在 Oracle 10g 上处理以下 2 个表。我正在尝试一项相当简单的任务,但无法正确查询,可能是由于我对基础知识缺乏了解。我想从 TEMP 中查询出 BMF 中不存在的 account_no。
两个表: 表 1:BMF:1372 行
account_no | trans_amount | tracking_id
8149817 | 8100 | 72422912
8197743 | 9100 | 72422913
7165129 | 8100 | 72422914
8625861 | 8100 | 72422915
8463378 | 2100 | 72422916
8213330 | 3100 | 72422917
表 2:temp:1373 行 -- BMF 中缺少 TEMP 中的唯一一个 account_no
account_no
8149817
8197743
7165129
8625861
8463378
8213330
84633
48
预期结果: 8463348 -- 因为这个数字不在 BMF 表中。
我的查询:
select a1.account_no from TEMP a1, bmf a2
where a2.tracking_id between 72422912 and 72424283
and a1.account_no != a2.account_no
任何带有正确查询的指针都会有所帮助
问候, 新手
【问题讨论】:
【参考方案1】:SELECT account_no FROM temp
WHERE NOT EXISTS (SELECT account_no FROM bmf
WHERE bmf.account_no = temp.account_no)
这将与此处其他答案中的 SQL 具有相同的执行计划,但它更清楚地说明了意图(至少对我而言)。
【讨论】:
【参考方案2】:您想要所有列值,它们在一组数据 (temp) 中但不在另一组数据 (bmf) 中?这就是"Minus" operator 所做的。
select account_no from TEMP
minus
select account_no from bmf
编辑: 添加文档链接
【讨论】:
【参考方案3】:SELECT account_no
FROM TEMP
WHERE acount_no NOT IN (SELECT account_no FROM BMF)
【讨论】:
【参考方案4】:试试
select a1.account_no from TEMP a1 left join bmf a2
where a2.tracking_id between 72422912 and 72424283
and a2.account_no = NULL
使用左连接,然后只取没有对应条目的条目
【讨论】:
【参考方案5】:您的连接语法是 Oracle 的 discouraged 用于外部连接。
您可以进行左外连接并排除未连接的列;这应该是最有效的方法。像这样的:
SELECT a1.account_no FROM TEMP a1
LEFT JOIN bmf a2 ON a1.account_no = a2.account_no
WHERE (a2.tracking_id between 72422912 and 72424283)
AND a2.account_no IS NULL
【讨论】:
您能否添加对“被 Oracle 劝阻”评论的引用? 我宁愿有一个 NOT EXIST 或 NOT IN 查询(OP 明确要求“来自 BMF 中不存在的 TEMP”的行)。 OUTER JOIN + NULL 的合成器很尴尬 @Vincent:在附加查询中使用 NOT IN 的习惯会很快导致嵌套的内部查询,这完全是性能杀手。既然我们在谈论 SQL,我们应该处理集合,而不是过程循环的构造...... @Lucero:实际上 NOT IN 将生成与 OUTER JOIN + NULL 完全相同的 ANTI-JOIN 计划。在 Svetlozar 的解决方案和 zendar 的解决方案中都没有内部查询(试试看)。 @Vincent:我知道。这就是为什么我写了“可以快速导致嵌套的内部查询”——当人们以更复杂的方式使用外部查询中的列时。以上是关于在 SQL 中查找表之间缺失的数字的主要内容,如果未能解决你的问题,请参考以下文章