寻找一种更优雅的方式来解决这个SQL查询

时间:2016-04-25 14:27:04

标签: sql

我收到了一个具有

模式的场景

产品:

maker   model   type
A   1232    PC
A   1233    PC
A   1276    Printer
A   1298    Laptop
A   1401    Printer
A   1408    Printer
A   1752    Laptop
B   1121    PC
B   1750    Laptop
C   1321    Laptop
D   1288    Printer
D   1433    Printer
E   1260    PC
E   1434    Printer
E   2112    PC
E   2113    PC

查询是

  

让只生产一种产品类型且不止一种产品的制造商   模型。

     

输出列应该是制造商和类型。

这就是我想出来的。

select distinct maker, type
from Product
where maker in (select maker
                from Product
                group by maker, type
                having count(model) > 1
                except
                select maker
                from 
                (
                    select distinct maker, type
                    from Product
                ) A
                group by maker
                having count(type) > 1)

我知道这看起来并不优雅,所以我想知道是否有人能提出更好的选择并解释为什么它比上述查询更好。

编辑:请确保答案只有两列宽

制造商,输入

3 个答案:

答案 0 :(得分:2)

SELECT maker, MIN(type) as type
FROM Product
GROUP BY maker
HAVING COUNT(DISTINCT type) = 1 AND COUNT(DISTINCT model) > 1;

答案 1 :(得分:1)

select count(distinct model) as unique_model_count,
       count(distinct type) as unique_type_count,
       maker
from Product
group by maker
having unique_type_count=1 and unique_model_count>1

答案 2 :(得分:1)

一种方法使用existsnot exists

select distinct p.maker, p.type
from product p
where exists (select 1
              from product p2
              where p2.maker = p.maker and p2.type = p.type and p2.model <> p.model
             ) and
      not exists (select 1
                  from product p2
                  where p2.maker = p.maker and p2.type <> p.type
                 );

另一个版本使用显式聚合:

select p.maker, p.type
from product p
where not exists (select 1
                  from product p2
                  where p2.maker = p.maker and p2.type <> p.type
                 )
group by p.maker, p.type
having min(model) <> max(model);

并且,为了完整性,这里是一个仅使用窗口函数的版本:

select p.model, p.type
from (select p.*,
             min(type) over (partition by maker) as mintype,
             max(type) over (partition by maker) as maxtype,
             row_number() over (partition by maker, type order by model) as seqnum,
             count(*) over (partition by maker, type) as cnt
      from product p
     ) p
where seqnum = 1 and
      mintype = maxtype and
      cnt > 1;
相关问题