2012-01-25 117 views
1

我的问题是否有更快的方式来查询以下内容?SQL - 按不同值分组

我使用Oracle 10g

说我有一个表,制造商和汽车,我要算列“Car.Name”的所有事件。这里是我会怎么做它:

SELECT manuf.Name, COUNT(car1.Name), COUNT(car2.Name), COUNT(car3.Name) 
FROM Manufacturer manuf 
LEFT JOIN (SELECT * FROM Car c where c.Name = 'Ferrari1') car1 ON manuf.PK = car1.ManufPK 
LEFT JOIN (SELECT * FROM Car c where c.Name = 'Ferrari2') car2 ON manuf.PK = car2.ManufPK 
LEFT JOIN (SELECT * FROM Car c where c.Name = 'Ferrari3') car3 ON manuf.PK = car3.ManufPK 
GROUP BY manuf.Name 

通缉结果:

Manufacturer | Ferrari1 | Ferrari2 | Ferrari3 
---------------------------------------------- 
Fiat   | 1  | 0  | 5 
Ford   | 2  | 3  | 0 

我很少LEFT JOIN的尝试这样做,它工作得很好。但是当我添加了很多(如90+)时,它超慢(超过1分钟)。

我的问题,有没有更快的方法来做这个查询?

+0

你能告诉我们什么是你以前的查询? – everton

+0

@WoF_Angel您使用哪种RDBMS?在MySQL中,您可以考虑在MSSQL中使用'GROUP_CONCAT'关于'PIVOT' –

+1

[通过正确的索引,多个连接可能至少会像PIVOT/GROUP BY一样执行](http://stackoverflow.com/questions/ 7448453/sql-server-pivot-vs-multiple-join/7449213#7449213) –

回答

3

如果你很高兴看到汽车倒计时页面,请尝试:

select m.Name manufacturer_name, 
     c.Name car_name, 
     count(*) 
from Manufacturer m 
left join Car c 
     on m.PK = c.ManufPK and c.Name in ('Ferrari1','Ferrari2','Ferrari3') 
group by m.Name, c.Name 

如果你需要看到整个页面各个汽车,尝试:

select m.Name manufacturer_name, 
     sum(case c.Name when 'Ferrari1' then 1 else 0 end) Ferrari1_Count, 
     sum(case c.Name when 'Ferrari2' then 1 else 0 end) Ferrari2_Count, 
     sum(case c.Name when 'Ferrari3' then 1 else 0 end) Ferrari3_Count 
from Manufacturer m 
left join Car c 
     on m.PK = c.ManufPK and c.Name in ('Ferrari1','Ferrari2','Ferrari3') 
group by m.Name 
+0

他提到过。 – everton

+2

@aF那么是什么?这不适合需求 - 所以我们需要一些细化的问题 –

+0

我用你的第二个建议,工作得很好。谢谢。 –

0
SELECT manuf.Name, COUNT(DISTINCT c.Name) 
FROM Manufacturer manuf 
LEFT JOIN Car c ON manuf.PK = c.ManufPK 
GROUP BY manuf.Name 

OR根据您的需要

SELECT manuf.Name, c.Name, COUNT(*) Cnt 
FROM Manufacturer manuf 
LEFT JOIN Car c ON manuf.PK = c.ManufPK 
GROUP BY manuf.Name, c.Name 

PS:你的问题不是很清楚。提供了一些有用的结果集细化答案

+0

这不会给出同一行中的所有计数。 –

+0

@MarkBannister查看评论回复 –

0

你也可以试试这个:

SELECT manuf.Name 
    , car1.cnt AS Ferrari1 
    , car2.cnt AS Ferrari2 
    , car3.cnt AS Ferrari3 
FROM 
     Manufacturer AS manuf 
    LEFT JOIN 
     (SELECT ManufPK, COUNT(*) AS cnt 
     FROM Car 
     WHERE Name = 'Ferrari1' 
     GROUP BY ManufPK 
    ) AS car1 
    ON car1.ManufPK = manuf.PK 
    LEFT JOIN 
     (SELECT ManufPK, COUNT(*) AS cnt 
     FROM Car 
     WHERE Name = 'Ferrari2' 
     GROUP BY ManufPK 
    ) AS car2 
    ON car2.ManufPK = manuf.PK 
    LEFT JOIN 
     (SELECT ManufPK, COUNT(*) AS cnt 
     FROM Car 
     WHERE Name = 'Ferrari3' 
     GROUP BY ManufPK 
    ) AS car3 
    ON car3.ManufPK = manuf.PK 
ORDER BY manuf.Name