消除SQL命令的“不在”

时间:2013-04-03 16:55:10

标签: sql oracle

我想获取一个Oracle表的示例,但不包括另一个表中的条目。我有一个目前有效的查询,但我很确定当子选择获得超过1000条记录时它会爆炸。

select user_key from users sample(5)
where active_flag = 'Y'
and user_key not in (
    select user_key from user_validation where validation_state <> 'expired'
);

如果没有 not in,如何重写。我想过使用minus,但随着新条目被添加到user_validation表中,我的样本量会继续下降。

3 个答案:

答案 0 :(得分:3)

您可以使用left outer join

执行此操作
select *
from (select u.user_key,
             count(*) over () as numrecs
      from users u left outer join
           user_validation uv
           on u.user_key = uv.user_key and
              uv.validation_state <> 'expired'
      where u.active_flag = 'Y' and uv.user_key is null
     ) t
where rownum <= numrecs * 0.05

您正在使用示例子句。目前尚不清楚您是否只想要选择5%的不匹配项,或者您希望5%的数据不匹配。这是后者。

编辑:根据作者的评论添加了示例:

select user_key from (
  select u.user_key, row_number() over (order by dbms_random.value) as randval
  from users u 
    left outer join user_validation uv 
    on u.user_key = uv.user_key 
    and uv.validation_state <> 'expired'
  where u.active_flag = 'Y' 
  and uv.user_key is null
) myrandomjoin where randval <=100;

答案 1 :(得分:2)

select us.user_key
from users us -- sample(5)
where us.active_flag = 'Y'
and NOT EXISTS (
    SELECT *
    from user_validation nx
    where nx.user_key = us.user_key
    AND nx.validation_state <> 'expired'
    );
BTW:我评论了样本(5)因为我不知道它意味着什么。 (我坚信这不相关)

答案 2 :(得分:1)

select u.user_key from users u, user_validation uv
where u.active_flag = 'Y'
and u.user_key=uv.user_key 
uv.validation_state= 'expired';

这是一个双重否定查询,x不在非过期ID列表中,相当于x在过期ID列表中,这就是我所做的,除了将子查询更改为连接之外。