sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvorfor kan jeg ikke ekskludere afhængige kolonner fra "GROUP BY", når jeg samler med en nøgle?

Fordi kun PK'en dækker alle kolonner i en underliggende tabel i GROUP BY klausul. Derfor virker din første forespørgsel. En UNIQUE begrænsning ikke.

Kombinationen af ​​en UNIQUE, der ikke kan udskydes og en NOT NULL begrænsning ville også kvalificere sig. Men det er ikke implementeret - samt nogle andre funktionelle afhængigheder kendt af SQL-standarden. Peter Eisentraut, hovedforfatteren af ​​indslaget, havde mere i tankerne, men det blev på det tidspunkt fastslået, at efterspørgslen er lav, og de tilknyttede omkostninger kan være høje. Se diskussionen om funktionen på pgsql-hackere.

Manualen:

Når GROUP BY er til stede, eller der er aggregerede funktioner til stede, er den ikke gyldig for SELECT listeudtryk for at referere til ugrupperede kolonner undtagen inden for aggregerede funktioner, eller når den ugrupperede kolonne er funktionelt afhængig af de grupperede kolonner, da der ellers ville være mere end én mulig værdi at returnere for en ugrupperet kolonne. Der eksisterer en funktionel afhængighed, hvis de grupperede kolonner (eller en undergruppe deraf) er den primære nøgle i tabellen, der indeholder den ugrupperede kolonne.

Og mere eksplicit:

PostgreSQL genkender funktionel afhængighed (tillader kolonner at blive udeladt fra GROUP BY ) kun når en tabels primære nøgle er inkluderet i GROUP BY liste. SQL-standarden specificerer yderligere betingelser, der skal genkendes.

Siden c.vin er UNIQUE NOT NULL , kan du rette din anden forespørgsel ved at bruge kolonnen PK i stedet:

...
group by c.id;

Bortset fra, mens referentiel integritet håndhæves, og hele tabellen forespørges, kan begge de givne forespørgsler være væsentligt billigere:aggregerede rækker i appraisal før sammenføjningen. Dette fjerner behovet for at GROUP BY i den ydre SELECT a priori. Ligesom:

SELECT c.vin, c.color, c.brand
     , a.min_appraisal
     , a.max_appraisal
FROM   car c
LEFT   JOIN (
   SELECT car_vin
        , min(price) AS min_appraisal
        , max(price) AS max_appraisal
   FROM   appraisal
   GROUP  BY car_vin
   ) a ON a.car_vin = c.vin;

Se:

  • Flere array_agg()-kald i en enkelt forespørgsel

Relateret:

  • SQL-sætning, der fungerer i MySQL, virker ikke i Postgresql - Sum &group_by rails 3
  • PostgreSQL - GROUP BY-klausul



  1. TNS-12519 uden maksimale processer nået

  2. MariaDB introducerer TO_CHAR()

  3. MySQL FULDSTÆNDIG JOIN?

  4. Er det muligt at slå tilbudsbehandling fra i Postgres COPY-kommandoen med CSV-format?