重写使用IN的sql命令

时间:2014-09-21 22:43:47

标签: sql

我有三张桌子:

Product(maker, model, type)
PC(model, speed, ram, hd, price)
Laptop(model, speed, ram, hd, screen, price)

我正在努力寻找销售笔记本电脑而不是电脑的制造商。我想我已经通过以下命令实现了这一目标:

select product.maker
from product
where product.maker not in 
    (select maker
    from pc, product
    where product.model = pc.model)
and product.maker in 
    (select maker
    from laptop, product
    where product.model = laptop.model);

但是我想在不使用IN和NOT IN的情况下重写它。

3 个答案:

答案 0 :(得分:1)

如果您不想使用not existsnot in,可以使用left join ... is null

select distinct p.maker
from product p
join laptop l on l.model = p.model
left join pc on pc.model = p.model
where pc.model is null

答案 1 :(得分:1)

您应该可以使用连接重写此内容:

select distinct p.maker
from product p
left outer join product p1 on p.maker=p1.maker
    inner join pc on p1.model = pc.model 
inner join product p2 on p.maker=p2.maker
    inner join laptop on p2.model = laptop.model
where pc.model is null

product在您的查询中使用了三次;这个查询做同样的事情。但是,由于它使用没有子查询的ANSI连接,product与别名一起使用。

答案 2 :(得分:1)

如果您想使用join执行此操作,我建议采用以下方法:

select p.maker
from product p left outer join
     pc
     on p.model = pc.model left outer join
     laptop l
     on p.model = l.model
group by p.maker
having sum(case when pc.model is not null then 1 else 0 end) = 0 and
       sum(case when l.model is not null then 1 else 0 end) > 0;

having子句可以等效地表示为:

having max(pc.model) is null and
       max(l.model) is not null;

使用not exists重写此内容仍然需要在子查询中加入。我怀疑type字段可能包含pclaptop等信息。如果是这样,那么最简单的方法是:

select p.maker
from product p
group by p.maker
having sum(case when p.type = 'pc' then 1 else 0 end) = 0 and
       sum(case when p.type = 'laptop' then 1 else 0 end) > 0;

或者,或者:

select distinct pl.maker
from product pl left join
     product pp
     on pp.maker = pl.maker and
        pp.type = 'pc'
where pl.type = 'laptop' and pp.maker is null;