Warum nicht "SELECT foo. * ... GROUP BY foo.id" in Postgres?

8

Ich habe eine Abfrage wie folgt:

%Vor%

Das hat mit SQLite und MySQL gut funktioniert. Postgres beschwert sich darüber, dass ich nicht alle Spalten von foo in die group by -Klausel aufgenommen habe. Warum ist das? Ist es nicht genug, dass foo.id einzigartig ist?

    
Sijmen Mulder 16.07.2009, 07:39
quelle

4 Antworten

27

Nur für den Fall, dass andere Leute über diese Frage stolpern:

Beginnend mit PostgreSQL 9.1 ist es ausreichend, die Spalten des Primärschlüssels in der group by-Klausel aufzulisten (so würde das Beispiel aus der Frage jetzt funktionieren).

    
a_horse_with_no_name 31.05.2012, 21:58
quelle
3

Einige Datenbanken sind entspannter, für gut und schlecht. Die Abfrage ist unspezifisch, daher ist das Ergebnis ebenfalls unspezifisch. Wenn die Datenbank die Abfrage zulässt, gibt sie einen Datensatz aus jeder Gruppe zurück, und es ist egal, welcher. Andere Datenbanken sind spezifischer und erfordern, dass Sie den gewünschten Wert aus der Gruppe angeben. Sie werden nicht zulassen, dass Sie eine Abfrage mit einem unspezifischen Ergebnis schreiben.

Die einzigen Werte, die Sie ohne Aggregat auswählen können, sind die in der group by -Klausel:

%Vor%

Sie können Aggregate verwenden, um andere Werte zu erhalten:

%Vor%

Wenn Sie alle Werte aus der Foo-Tabelle haben wollen, können Sie sie entweder alle in die group by -Klausel setzen (wenn dies das richtige Ergebnis ergibt):

%Vor%

Oder Sie können der Tabelle eine Unterabfrage hinzufügen:

%Vor%     
Guffa 16.07.2009 10:43
quelle
3

Was genau hätten Sie postgresql ausgegeben? Sie verwenden eine Aggregatfunktion und versuchen, "etwas" auszugeben.

Ah. Ich sehe was du machen willst. Verwenden Sie einen Subselect.

%Vor%

Erkundigen Sie sich, dass der Plan jedoch gut aussieht. Ein Subselect ist nicht immer schlecht. Ich habe gerade mit einer Datenbank überprüft, die ich verwende, und mein Ausführungsplan war gut für diese Abfrage.

Ja, in der Theorie würde die Gruppierung nach foo.id ausreichen (d. h .: Ihre Abfrage plus "group by foo.id"). Aber anscheinend (ich habe es getestet) postgresql wird das nicht tun. Die andere Option ist "Gruppierung nach foo.id, foo.foo, foo.bar, foo.baz" und alles andere was in "foo. *" Steht.

Ein anderer Weg, zu dem Guffa gehört, ist dies:

%Vor%

Dies sind jedoch zwei Abfragen (eine Unterabfrage, die nur einmal ausgeführt wird), die zwar eine Rolle spielen können, aber wahrscheinlich auch nicht. Wenn Sie einfach auf "foo. *" Verzichten können, können Sie die zweite Version verwenden, die explizit nach allen Spalten gruppiert ist.

    
Thomas 16.07.2009 07:47
quelle
1

Eine GROUP BY -Klausel erfordert, dass jede Spalte, die die Abfrage zurückgibt, entweder eine Spalte in der GROUP BY -Anweisung oder eine Aggregatfunktion ist (z. B. COUNT in Ihrem Beispiel). Ohne zu sehen, was Ihre GROUP BY -Klausel ist oder was die Spalten von foo sind, ist es schwer zu sagen, was genau passiert, aber ich würde vermuten, dass foo.* versucht, eine oder mehrere Spalten zurückzugeben nicht in Ihrer GROUP BY -Klausel.

Dies ist wirklich eine allgemeine Eigenschaft von SQL und sollte nicht für PostgreSQL spezifisch sein. Keine Ahnung, warum es mit SQLite oder MySQL für Sie funktioniert hat - vielleicht sind alle Spalten in foo.* tatsächlich in Ihrer GROUP BY -Klausel, aber PostgreSQL kann das nicht herausfinden - versuchen Sie also, alle Spalten von% co_de aufzulisten % explizit.

    
Martin B 16.07.2009 07:53
quelle

Tags und Links