使用连接取消对此查询的限制

时间:2012-01-25 19:09:35

标签: sql join

我的查询有效:

select name, location_id from all_names
where location_id in (1,2,3)
and name in(select name from my_names) 
and (name, location_id) not in (select name,location_id from my_names);

此查询的目的是查找all_names中不在my_names中的所有name,location_id元组,只要这些名称在my_names中。

相对业余的sql我试图做一些研究来修复这个查询,但它不太有用。基本上,我尝试使用my_name和all_names中的外连接(name,location_id)元组,并标识那些返回null的行,因为那些行是没有匹配的行。

select data.name, data.location_id
from
(select all.name, all.location_id, my.name, my.location_id l_id
from (select name, location_id
from all_names
where location_id in (1,2,3)
)all,
(select name, location_id
from my_names
)my
where all.name = my.name(+)
and all.location_id = my.location_id(+)) data
where data.l_id is null
and data.name is null;

每当我添加“where data.name ='SomeSpecificName'”时,这都有效,但是当我在没有它的情况下运行它时,它会返回waaay太多的行。你能帮我理解我哪里出错吗?

4 个答案:

答案 0 :(得分:2)

我认为您当前的查询很好。

INNOT IN比您想象的更有效率。对此进行查询计划并与RedFilter的答案进行比较。

答案 1 :(得分:1)

select a.name, a.location_id 
from all_names a
inner join my_names m on a.name = m.name
left outer join my_names m2 on a.name = m2.name and a.location_id = m2.location_id
where a.location_id in (1,2,3)
    and m2.name is null

答案 2 :(得分:0)

或者

SELECT
    name,
    location_id
FROM
    all_names a
WHERE
    location_id IN (1,2,3) AND
    name IN (SELECT * FROM my_names) AND
    NOT EXISTS (SELECT * 
                FROM my_names m 
                WHERE m.location_id=a.location_id AND m.name=a.name)

答案 3 :(得分:0)

不确定查询计划是什么样的,但您可以尝试:

select a.name, a.location_id
from all_names a, my_names m
where a.location_id in (1,2,3)
and a.name = m.name
minus
select name, location_id
from my_names

这是一种非常清晰的方式来表达您的意图,并有机会使用经常被遗忘的minus运算符。