1

My question, is there a faster way to the following query?

I'm using ORACLE 10g

Say i have a table Manufacturer and Car, and i want to count all occurrences of the column 'Car.Name'. here is How i'd do it:

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

Wanted Results:

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

I tried this with few LEFT JOINs, and it worked fine. But when i added a lot (like 90+), it was ultra slow (more than 1 minute).

My question, is there a faster way to do this query?

WoF_Angel
  • 2,569
  • 9
  • 35
  • 54

3 Answers3

3

If you are happy to see the cars counted down the page, try:

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

If you need to see individual cars across the page, try:

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
SELECT manuf.Name, COUNT(DISTINCT c.Name)
FROM Manufacturer manuf 
LEFT JOIN Car c ON manuf.PK = c.ManufPK
GROUP BY manuf.Name

OR depending on your needs

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: Your question is not very clear. Provide some wanted resultset to refine the answer

Oleg Dok
  • 21,109
  • 4
  • 45
  • 54
0

You can also try this:

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
ypercubeᵀᴹ
  • 113,259
  • 19
  • 174
  • 235