2011-01-23 4 views
3

Comment rendre cette requête SQL plus efficace?Rendre la requête SQL plus efficace

SELECT 
    (SELECT COUNT(*) FROM table WHERE price < 10) AS priceUnder10, 
    (SELECT COUNT(*) FROM table WHERE price BETWEEN 10 AND 20) AS price10to20, 
    (SELECT COUNT(*) FROM table WHERE price > 20) AS priceOver20, 
    (SELECT COUNT(*) FROM table WHERE colour = 'Red') AS colourRed, 
    (SELECT COUNT(*) FROM table WHERE colour = 'Green') AS colourGreen, 
    (SELECT COUNT(*) FROM table WHERE colour = 'Blue') AS colourBlue; 

J'ai déjà des index sur les colonnes price et colour, donc je suis à la recherche d'une meilleure façon d'agréger les données.

J'ai examiné en utilisant GROUP BY, HAVING, les auto-jointures et les fonctions de fenêtre, mais je n'arrive pas à obtenir le même résultat.

Toutes les suggestions très appréciées.

Répondre

8
SELECT 
     COUNT(CASE WHEN price < 10 THEN 1 END) AS priceUnder10, 
     COUNT(CASE WHEN price BETWEEN 10 AND 20 THEN 1 END) AS price10to20, 
     COUNT(CASE WHEN price> 20 THEN 1 END) AS priceOver20, 
     COUNT(CASE WHEN colour = 'Red' THEN 1 END) AS colourRed, 
     COUNT(CASE WHEN colour = 'Green' THEN 1 END) AS colourGreen, 
     COUNT(CASE WHEN colour = 'Blue' THEN 1 END) AS colourBlue 
from YourTable 
WHERE price IS NOT NULL OR colour IN ('Red','Green','Blue') 
+1

Merci, excellente réponse, mais pourquoi est la 'WHERE' nécessaire? – gjb

+2

@gjb -Il pourrait bien ne pas être mais imaginez que vous avez une table de 1 000 000 lignes et seulement 1 ligne a un prix ou une couleur non nulle dans «Rouge», «Vert», «Bleu» Les autres 999 999 lignes ne feront pas différence au résultat, mais encore être scanné sans elle. Bien sûr, vous savez peut-être que vos données n'ont pas cette distribution (le «prix» pourrait même ne pas être nul) et il pourrait aussi bien être supprimé! –

2

Selon la façon dont votre base de données gère les expressions booléennes, ceci:

select sum(price<10),sum(price between 10 and 20)... from tab; 

ou cette

select sum(case when price<10 then 1 else 0 end),sum(case when price between 10 and 20 then 1 else 0 end)... from tab; 

pourrait aider.

0
SELECT count(*) as products, 

if(price < 10, 'price band 1', 
if (price between 10 and 20, 'price band 2', 
    'price band 3' 
) 
) as priceband, 
    t.colour 

from table t 
group by t.colour, pricebrand 

Cela vous donnera

products colour priceband 
53   red  price band 1 
65   red  price band 2 
12   blue  price band 1 
23   blue  price band 2 

etc.

+0

Cela imbrique les résultats, ce qui n'est pas tout à fait ce que je cherchais. Encore, utile de savoir, alors merci. – gjb

Questions connexes