2009-03-10 7 views
8

Pourquoi ne puis-je pas utiliser une colonne temporaire dans la clause where?Comment utiliser une colonne temp dans la clause where

Par exemple, cette requête:

Select 
    product_brand, 
    (CASE WHEN COUNT(product_brand)>50 THEN 1 ELSE 0 END) AS brand_count 
FROM 
    products 
WHERE 
    1 
GROUP BY 
    product_brand 

Cela fait apparaître deux colonnes, l'une appelée product_brand et un appelé brand_count. brand_count est créé à la volée et est toujours 1 ou 0 selon qu'il y a 50 ou des produits avec cette marque.

Tout cela fait sens pour moi, sauf que je ne peux pas sélectionner uniquement si brand_count = 1 comme dans cette requête ci-dessous:

Select 
    product_brand, 
    (CASE WHEN COUNT(product_brand)>50 THEN 1 ELSE 0 END) AS brand_count 
FROM 
    products 
WHERE 
    brand_count = 1 
GROUP BY 
    product_brand 

qui me donne cette erreur:

#1054 - Unknown column 'brand_count' in 'where clause' 

Répondre

13

Utilisation HAVING à la place:

Select 
    product_brand, 
    (CASE WHEN COUNT(product_brand)>50 THEN 1 ELSE 0 END) AS brand_count 
    FROM products 
    GROUP BY product_brand 
    HAVING brand_count = 1 

WHERE est évalué avant leGROUP BY. HAVING est évalué après.

+0

Vous avez tort. Cela ne fonctionne pas en ayant aussi. – thorn

+0

@thorn: ça a toujours marché pour moi en MySQL. Peut-être qu'il y a quelque chose d'autre qui ne va pas dans votre requête? Quelle version de MySQL utilisez-vous, et avez-vous l'une des options strictes activées? – derobert

+0

Désolé. J'ai confondu MySQL avec MS SQL Server. – thorn

0

Parce qu'il a aucune idée de ce que cette colonne est jusqu'à ce que le traitement soit terminé.

Si vous souhaitez accéder à la colonne par ce nom, vous devrez utiliser une sous-requête, sinon vous devrez qualifier la colonne sans le nom que vous lui avez donné, en répétant votre déclaration de cas.

2

Parce que dans SQL les colonnes sont d'abord "sélectionnées" puis "projetées".

+0

C'est beaucoup plus concis que ma tentative d'expliquer :) – TheTXI

+0

Merci TheTXI: P, hourra pour les cours de conception DB, ils ont finalement payé. –

2

Vous devez utiliser la clause complète, vous aurez besoin:

Select 
    product_brand, 
    (CASE WHEN COUNT(product_brand)>50 THEN 1 ELSE 0 END) AS brand_count 
FROM products 
WHERE 
    (CASE WHEN COUNT(product_brand)>50 THEN 1 ELSE 0 END) = 1 
GROUP BY product_brand 

C'est la même pour tout champ calculé dans une instruction SQL.

Pour simplifier:

Select Max(Points) as Highest where Highest > 10 

ne fonctionnera pas, mais:

Select Max(Points) as Highest where Max(Points) > 10 

volonté. C'est pareil dans votre cas.

0

Si je lis votre intention correctement, vous pouvez ré-écrire cette requête comme suit:

Select 
product_brand, 
COUNT(product_brand) AS brand_count 
FROM 
products 
GROUP BY 
product_brand 
HAVING 
COUNT(product_brand) > 50 

Cela vous donnera tous les product_brands qui ont un count > 50 et aussi vous montrer le compte pour chacun.

Questions connexes