2016-04-25 89 views
2

有人递给我一个场景,具有寻找解决这个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) 

我知道这似乎不优雅的以任何方式,所以我想知道是否有人能想出一个更好的选择和为什么它比上述的查询更好地解释。


编辑:请确保答案是仅仅两列宽是

设备,类型

+1

能否请你添加一个标签为您的RDBMS引擎? – amphetamachine

+0

子查询可以简单地是一个GROUP BY,在HAVING中有条件。 – jarlh

回答

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; 
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 
+0

_无限_这个“正确”的答案!但是,我认为需要包括“制造商”和“类型”一个简单的解决这里显示的内容。 (没有尝试过......)我不是100% - 确保可以按照“having”子句中所示使用列名,但可能必须在此重复“count()”表达式。 。 。? –

+0

正确的逻辑,但如果未指定的RDBMS在having子句中不允许别名,则可能会引发错误。 –

+0

@MikeRobinson。 。 。我认为这不是正确的答案,因为它不包含'type'。 –

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

在大多数数据库中,这将返回一个错误('type'不是开始汇总)。在MySQL中,它只会为每个制造商返回一个“类型”。 –

+0

我知道,但问题是哪个制造商生产一种类型,所以我认为它会好起来的 – Autor69