web-dev-qa-db-fra.com

PostgreSQL Où condition de comptage

J'ai la requête suivante dans PostgreSQL:

SELECT 
    COUNT(a.log_id) AS overall_count
FROM 
    "Log" as a, 
    "License" as b 
WHERE 
    a.license_id=7 
AND 
    a.license_id=b.license_id 
AND
    b.limit_call > overall_count
GROUP BY 
    a.license_id;

Pourquoi ai-je cette erreur:

ERREUR: la colonne "compte_ensemble" n'existe pas

Ma structure de table:

License(license_id, license_name, limit_call, create_date, expire_date)
Log(log_id, license_id, log, call_date)

Je souhaite vérifier si une licence a atteint la limite d'appels au cours d'un mois spécifique.

33
Hadi
SELECT a.license_id, a.limit_call
     , count(b.license_id) AS overall_count
FROM   "License"  a
LEFT   JOIN "Log" b USING (license_id)
WHERE  a.license_id = 7 
GROUP  BY a.license_id  -- , a.limit_call  -- add in old versions
HAVING a.limit_call > count(b.license_id)

Points majeurs

  • Dans les versions antérieures à PostgreSQL 9.1, vous devez ajouter limit_call À la clause GROUP BY. À partir de la version 9.1, il suffit d'avoir la clé primaire dans la clause GROUP BY. Les notes de version pour 9.1 :

    Autoriser les colonnes autres que GROUP BY Dans la liste cible de requête lorsque la clé primaire est spécifiée dans la clause GROUP BY

  • Votre condition WHERE doit passer à la clause HAVING car elle fait référence au résultat d'une fonction d'agrégation. Et vous ne pouvez pas faire référence aux colonnes de sortie (alias de colonne) dans la clause HAVING, où vous ne pouvez référencer que les colonnes d'entrée. Il faut donc répéter l'expression. Par documentation:

    Le nom d'une colonne de sortie peut être utilisé pour faire référence à la valeur de la colonne dans les clauses ORDER BY Et GROUP BY, Mais pas dans les clauses WHERE ou HAVING; là, vous devez écrire l'expression à la place.

  • J'ai inversé l'ordre des tables dans la clause FROM et nettoyé un peu la syntaxe pour la rendre moins confuse. USING est juste une commodité de notation ici.

  • J'ai utilisé LEFT JOIN au lieu de JOIN, donc vous n'excluez pas de licences sans aucun journal.

  • Je conseillerais pas d'utiliser identificateurs de casse mixtes dans Postgres si possible. Très sujet aux erreurs.

  • Seules les valeurs non nulles sont comptées par count(). Puisque vous voulez compter entrées liées dans le tableau "Log" Il est plus sûr et légèrement moins cher à utiliser count(b.license_id). Cette colonne est utilisée dans la jointure, nous n'avons donc pas à nous soucier de savoir si la colonne peut être nulle ou non.
    count(*) est encore plus court et légèrement plus rapide. Si cela ne vous dérange pas d'obtenir un nombre de 1 Pour les lignes 0 Dans le tableau de gauche, utilisez-le.

46
Erwin Brandstetter

La requête where ne reconnaît pas votre alias de colonne, et en outre, vous essayez de filtrer les lignes après l'agrégation. Essayer:

SELECT 
COUNT(a.log_id) AS overall_count
FROM 
"Log" as a, 
"License" as b 
WHERE 
a.license_id=7 
AND 
a.license_id=b.license_id 
GROUP BY 
a.license_id
having b.limit_call > count(a.log_id);

La clause having est similaire à la clause where, sauf qu'elle traite les colonnes après une agrégation, tandis que la clause where fonctionne sur les colonnes avant une agrégation.

De plus, y a-t-il une raison pour laquelle vos noms de table sont placés entre guillemets?

6
user554546