我正在比较两个表,它们之间共享唯一的值,使用 NOT IN
中的函数 Oracle
但我现在
select count(distinct CHARGING_ID) from BILLINGDB201908 where CDR_TYPE='GPRSO'
输出为: 521254
对于所有计费id--<这是billingdb201908中唯一的计费id的总数
现在我想在billingdb201908表中找到同样存在于cbs\u chrg\u id\u aug表中的id
select count(distinct CHARGING_ID) from BILLINGDB201908 where CDR_TYPE='GPRSO'
AND charging_id IN (select CHARGINGID from CBS_CHRG_ID_AUG);
---结果回来了 315567
收费id存在于billingdb201908中,也存在于cbs\U chrg\U id\U aug中
现在我想找到在cbs\u chrg\u id\u aug中不存在但存在billingdb201908的收费id
select count(distinct CHARGING_ID) from prmdb.CDR_TAPIN_201908@prmdb where CDR_TYPE='GPRSO'
AND charging_id NOT IN (select CHARGINGID from CBS_CHRG_ID_AUG);
--结果回来了 0
!? 我应该去 205687
完全是因为 521254-315567
= 205687 ?
5条答案
按热度按时间zvms9eto1#
缺少的记录具有空值chargingid。
请尝试选择chargingid为空vs不为空的位置
lztngnrs2#
NOT IN
如果子查询中的任何值无效,则不返回任何行NULL
. 因此,我强烈建议NOT EXISTS
:我还建议将第一个查询改为
EXISTS
. 事实上,只是不要使用IN
以及NOT IN
使用子查询,就不会有这个问题。klr1opcd3#
我建议你
not exists
而不是not in
; 它是null
-安全,通常效率更高:ql3eal8s4#
您可以使用
LEFT OUTER JOIN
.sql返回cbs\u chrg\u id\u aug中不存在但存在billingdb201908的计费id列表-
mcvgt66p5#
这有两种危险
not in
当子查询键可能包含空值时:如果实际存在空值,则可能无法得到预期的结果(如您所发现的)。数据库实际上是正确的,尽管在sql历史上没有人预料到这个结果。
即使填充了所有键值,键列是否可能为null(如果未定义为
not null
)然后数据库必须进行检查以防出现空值,因此查询仅限于低效的逐行筛选操作,这可能会对大型卷执行灾难性的操作(这在历史上是正确的,尽管现在有一个空感知的反连接,因此性能问题可能不会那么严重。)原因是
1 <> null
是null
,不是false
. 如果用固定列表代替not in
子查询,它将是:这和
很明显
d.id <> null
永远不会是真的。这就是为什么你not in
查询未返回任何行。