我想获取一个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表中,我的样本量会继续下降。
答案 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列表中,这就是我所做的,除了将子查询更改为连接之外。