2010-01-17 5 views
0

Donc, je souhaite appliquer une condition WHERE à un champ affecté par une clause COUNT() AS. Ma requête ressemble actuellement à ceci:SQL WHEREing sur une table différente COUNT

SELECT new_tags.tag_id 
     , new_tags.tag_name 
     , new_tags.tag_description 
     , COUNT(DISTINCT new_tags_entries.entry_id) AS entry_count 
FROM (new_tags) 
JOIN new_tags_entries ON new_tags_entries.tag_id = new_tags.tag_id 
WHERE `new_tags`.`tag_name` LIKE '%w' 
AND `entry_count` < '1' 
GROUP BY new_tags.tag_id ORDER BY tag_name ASC 

Le bit qui est défaillant est le ENTRY_COUNT dans la clause WHERE - il ne sait pas ce que la colonne est ENTRY_COUNT. Ma table ressemble à ceci:

new_tags { 
    tag_id INT 
    tag_name VARCHAR 
} 

new_tags_entries { 
    tag_id INT 
    entry_id INT 
} 

Je veux filtrer les résultats par le nombre de entry_ids distincts new_tags_entries qui se rapportent à l'ID d'étiquette.

Avez-vous du sens?

Merci d'avance.

+1

Ne peut pas empêcher de remarquer 'ENTRY_COUNT < « 1''. Ne citez pas le '1' - vous n'essayez pas de voir si cela équivaut à une chaîne avec le contenu de''' que vous êtes en train de découvrir s'il y a moins d'une occurrence. –

Répondre

2

Pour filtrer sur les valeurs aggegated utiliser la clause HAVING ...

SELECT 
    new_tags.tag_id, new_tags.tag_name, 
    new_tags.tag_description, 
    COUNT(DISTINCT new_tags_entries.entry_id) AS entry_count 
FROM (new_tags) 
JOIN new_tags_entries ON new_tags_entries.tag_id = new_tags.tag_id 
WHERE `new_tags`.`tag_name` LIKE '%w' 
GROUP BY new_tags.tag_id 
HAVING COUNT(DISTINCT new_tags_entries.entry_id) < '1' 
ORDER BY tag_name ASC 
+0

C'est parfait, merci beaucoup. –

+0

en fait, le 'ORDER BY' devrait être après le' HAVING'. Certaines versions de MySQL peuvent autoriser l'ordre avant d'avoir, mais le standard sql nécessite que l'ordre apparaisse après le groupe et l'avoir. Par exemple, MySQL 5.1.36 ne permettra pas l'ordre avant d'avoir. –

+0

@Roland - bonne prise. J'ai peur de simplement couper le code affiché sans le lire correctement. – APC

1

Une jointure interne n'aura jamais un nombre inférieur à 1. Peut-être qu'une jointure à gauche et IS NULL seraient utiles. Cela, ou en utilisant SUM() à la place.

+0

+ pour le 'LEFT JOIN '. Je ne vois pas comment 'SUM' pourrait aider si –

+0

' SUM() 'pourrait aider si le nombre d'entrées est détenu dans un champ quelque part. –

0
SELECT 
    new_tags.tag_id, new_tags.tag_name, 
    new_tags.tag_description, 
    COUNT(DISTINCT new_tags_entries.entry_id) AS entry_count 
FROM (new_tags) 
LEFT JOIN new_tags_entries ON new_tags_entries.tag_id = new_tags.tag_id 
WHERE `new_tags`.`tag_name` LIKE '%w' 
GROUP BY new_tags.tag_id ORDER BY tag_name ASC 
HAVING `entry_count` < '1' 
1

Bien que la réponse de l'APC sera syntaxiquement correct, si le problème que vous essayez de résoudre est en effet: « Trouvez-moi tous new_tags qui n'a pas de news_tags_entries ", la requête avec INNER JOIN et GROUP BY et HAVING ne donnera pas le bon résultat. En fait, cela donnera toujours l'ensemble vide. Comme Ignacio Vazques Abrahams l'a souligné, un LEFT JOIN fonctionnera. Et vous n'avez même pas besoin du GROUP BY/HAVING:

SELECT news_tags.* 
FROM  news_tags 
LEFT JOIN news_tags_entries 
ON  news_tags.tag_id = news_tags_entries.tag_id 
WHERE  news_tags_entries.tag_id IS NULL 

(Bien sûr, vous pouvez toujours ajouter GROUP BY et HAVING si vous êtes intéressés de savoir combien d'entrées il y a, et non voulez juste trouver news_tags avec zéro news_tags_entries. Mais le LEFT JOIN de news_tags à news_tags_entries doit être là ou bien vous perdrez les news_tags qui ont pas d'articles correspondants dans news_tags_items)

Une autre façon plus explicite pour résoudre les « Donnez-moi tous les x pour lesquels il n'est pas y "est une solution corrélée NOT EXISTS:

SELECT news_tags.* 
FROM  news_tags 
WHERE NOT EXISTS (
      SELECT NULL 
      FROM news_tags_entries 
      WHERE news_tags_entries.tag_id = news_tags.tag_id 
     ) 

Bien agréable et explicite, cette solution est généralement boudé dans MySQL en raison de la performance plutôt mauvaise sous-requête