SQL - 按不同的值分组

时间:2012-01-25 11:36:09

标签: sql performance oracle10g group-by

我的问题是,有更快的方法来进行以下查询吗?

我正在使用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分钟)。

我的问题是,有更快的方法来进行此查询吗?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

,具体取决于您的需求

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:你的问题不是很清楚。提供一些想要的结果集来优化答案

答案 2 :(得分: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