sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL Waar tellen voorwaarde

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)

Sinds Postgres 9.1 dekt de primaire sleutel alle kolommen van een tabel in de GROUP BY clausule. In oudere versies zou je a.limit_call . moeten toevoegen naar de GROUP BY lijst. De release-opmerkingen voor 9.1:

Niet-GROUP BY Allow toestaan kolommen in de zoekdoellijst wanneer de primaire sleutel is opgegeven in de GROUP BY clausule

Verder lezen:

  • Waarom kan ik afhankelijke kolommen niet uitsluiten van `GROUP BY` als ik aggregeer met een sleutel?

De voorwaarde die u had in de WHERE clausule moet worden verplaatst naar de HAVING clausule omdat het verwijst naar het resultaat van een aggregatiefunctie (na WHERE is aangebracht). En u kunt niet verwijzen naar uitvoerkolommen (kolom aliassen) in de HAVING clausule, waar u alleen naar invoerkolommen kunt verwijzen. Dus je moet de uitdrukking herhalen. De handleiding:

De naam van een uitvoerkolom kan worden gebruikt om te verwijzen naar de waarde van de kolom inORDER BY en GROUP BY clausules, maar niet in de WHERE of HAVING clausules; daar moet je in plaats daarvan de uitdrukking uitschrijven.

Ik heb de volgorde van de tabellen in de FROM . omgedraaid clausule en de syntaxis een beetje opgeschoond om het minder verwarrend te maken. USING is hier slechts een notatie gemak.

Ik gebruikte LEFT JOIN in plaats van JOIN , dus u sluit geen licenties uit zonder logboeken.

Alleen niet-null-waarden worden geteld door count() . Omdat je gerelateerde inzendingen wilt tellen in tabel "Log" het is veiliger en iets goedkoper om count(b.license_id) . te gebruiken . Deze kolom wordt gebruikt in de join, dus we hoeven ons geen zorgen te maken of de kolom null kan zijn of niet.
count(*) is nog korter en iets sneller, maar toch. Als je het niet erg vindt om 1 te tellen voor 0 rijen in de linkertabel, gebruik die.

Terzijde:ik zou adviseren niet om identifiers voor hoofdletters en kleine letters te gebruiken in Postgres indien mogelijk. Zeer foutgevoelig.



  1. PostgreSQL, complexe query voor het berekenen van ingrediënten op recept

  2. postgresql-array uitpakken in rijen

  3. Hoe te controleren welke sloten op een tafel worden vastgehouden?

  4. CREATE TABLE in SQL - Alles wat u moet weten over het maken van tabellen in SQL