2012-01-25 124 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