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)
Siden Postgres 9.1 dækker den primære nøgle alle kolonner i en tabel i GROUP BY
klausul. I ældre versioner skal du tilføje a.limit_call
til GROUP BY
liste. Udgivelsesbemærkningerne til 9.1:
Tillad ikke-GROUP BY
kolonner i forespørgselsmållisten, når primærnøglen er angivet i GROUP BY
klausul
Yderligere læsning:
- Hvorfor kan jeg ikke ekskludere afhængige kolonner fra "GROUP BY", når jeg samler med en nøgle?
Den tilstand, du havde i WHERE
klausul skal flyttes til HAVING
klausul, da den refererer til resultatet af en aggregeret funktion (efter WHERE
er blevet anvendt). Og du kan ikke henvise til outputkolonner (kolonnealiaser) i HAVING
klausul, hvor du kun kan referere til inputkolonner. Så du skal gentage udtrykket. Manualen:
En outputkolonnes navn kan bruges til at henvise til kolonnens værdi iORDER BY
og GROUP BY
klausuler, men ikke i WHERE
eller HAVING
klausuler; der skal du i stedet skrive udtrykket ud.
Jeg vendte rækkefølgen af tabeller i FROM
klausul og ryddede lidt op i syntaksen for at gøre det mindre forvirrende. USING
er kun en notationsbekvemmelighed her.
Jeg brugte LEFT JOIN
i stedet for JOIN
, så du udelukker ikke licenser uden nogen log overhovedet.
Kun værdier, der ikke er nul, tælles af count()
. Da du vil tælle relaterede poster i tabel "Log"
det er mere sikkert og lidt billigere at bruge count(b.license_id)
. Denne kolonne bruges i joinforbindelsen, så vi skal ikke bekymre os om kolonnen kan være null eller ej.count(*)
er endnu kortere og lidt hurtigere, endnu. Hvis du ikke har noget imod at få en optælling på 1
for 0
rækker i den venstre tabel, brug det.
Bortset fra:Jeg vil fraråde ikke at bruge blandede store og små bogstaver i Postgres hvis muligt. Meget fejltilbøjelig.