PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Warum kann ich abhängige Spalten nicht von „GROUP BY“ ausschließen, wenn ich nach einem Schlüssel aggregiere?

Denn nur der PK deckt alle Spalten einer zugrunde liegenden Tabelle im GROUP BY ab Klausel. Daher funktioniert Ihre erste Abfrage. Ein UNIQUE Einschränkung nicht.

Die Kombination eines nicht aufschiebbaren UNIQUE und ein NOT NULL Einschränkung würde auch qualifizieren. Aber das ist nicht implementiert - ebenso wie einige andere funktionale Abhängigkeiten, die dem SQL-Standard bekannt sind. Peter Eisentraut, der Hauptautor des Features, hatte mehr im Sinn, aber es wurde damals festgestellt, dass die Nachfrage gering und die damit verbundenen Kosten hoch sein könnten. Siehe die Diskussion über das Feature auf pgsql-hackers.

Das Handbuch:

Wenn GROUP BY vorhanden ist oder Aggregatfunktionen vorhanden sind, ist es für SELECT nicht gültig Listenausdrücke auf nicht gruppierte Spalten verweisen, außer innerhalb von Aggregatfunktionen oder wenn die nicht gruppierte Spalte funktional von den gruppierten Spalten abhängig ist, da es sonst mehr als einen möglichen Wert geben würde, der für eine nicht gruppierte Spalte zurückgegeben werden könnte. Eine funktionale Abhängigkeit besteht, wenn die gruppierten Spalten (oder eine Teilmenge davon) der Primärschlüssel der Tabelle sind, die die nicht gruppierte Spalte enthält.

Und noch expliziter:

PostgreSQL erkennt funktionale Abhängigkeiten (wodurch Spalten aus GROUP BY weggelassen werden können ) nur, wenn der Primärschlüssel einer Tabelle im GROUP BY enthalten ist aufführen. Der SQL-Standard spezifiziert zusätzliche Bedingungen, die erkannt werden sollten.

Seit c.vin ist UNIQUE NOT NULL , können Sie Ihre zweite Abfrage korrigieren, indem Sie stattdessen die PK-Spalte verwenden:

...
group by c.id;

Abgesehen davon, während die referenzielle Integrität erzwungen und die gesamte Tabelle abgefragt wird, können beide angegebenen Abfragen wesentlich billiger sein:aggregierte Zeilen in appraisal vorher der Beitritt. Dadurch entfällt die Notwendigkeit von GROUP BY im äußeren SELECT a priori. Wie:

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;

Siehe:

  • Mehrere array_agg()-Aufrufe in einer einzigen Abfrage

Verwandte:

  • SQL-Anweisung, die in MySQL funktioniert, funktioniert nicht in Postgresql - Sum &group_by rails 3
  • PostgreSQL - GROUP BY-Klausel