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

Rails erweitern Felder mit Umfang, PG mag es nicht

Wie Frank erklärt hat, lehnt PostgreSQL jede Abfrage ab, die keinen reproduzierbaren Satz von Zeilen zurückgibt.

Angenommen, Sie haben eine Abfrage wie:

select a, b, agg(c)
from tbl
group by a

PostgreSQL wird es ablehnen, weil b wird in group by nicht angegeben Aussage. Führen Sie das dagegen in MySQL aus, und es wird akzeptiert. Wenn Sie im letzteren Fall jedoch ein paar Einfügungen, Aktualisierungen und Löschungen ausführen, ändert sich die Reihenfolge der Zeilen auf den Festplattenseiten.

Wenn der Speicher reicht, sind die Implementierungsdetails so, dass MySQL tatsächlich nach a, b sortiert und das erste b in der Menge zurückgibt. Aber soweit es den SQL-Standard betrifft, ist das Verhalten unspezifiziert – und PostgreSQL tut das nicht Sortieren Sie immer, bevor Sie Aggregatfunktionen ausführen.

Dies kann möglicherweise zu unterschiedlichen Werten von b führen im Ergebnissatz in PostgreSQL. Und daher gibt PostgreSQL einen Fehler aus, es sei denn, Sie sind genauer:

select a, b, agg(c)
from tbl
group by a, b

Was Frank hervorgehoben hat, ist, dass in PostgreSQL 9.1, wenn a der Primärschlüssel ist, dann können Sie b lassen nicht spezifiziert -- dem Planer wurde beigebracht, nachfolgende Gruppieren-nach-Felder zu ignorieren, wenn zutreffende Primärschlüssel eine eindeutige Zeile implizieren.

Insbesondere für Ihr Problem müssen Sie Ihre Gruppe so angeben, wie Sie es derzeit tun, plus jedes Feld, auf dem Sie Ihr Aggregat aufbauen, d. h. "widgets"."id", "widgets"."user_id", [snip] aber keine Sachen wie sum(amount) , die die zusammengefassten Funktionsaufrufe sind.

Als Nebenbemerkung zum Thema:Ich bin mir nicht sicher, wie Ihr ORM/Modell funktioniert, aber das generierte SQL ist nicht optimal. Viele dieser linken äußeren Joins scheinen innere Joins zu sein. Dies führt dazu, dass der Planer gegebenenfalls eine geeignete Verbindungsreihenfolge auswählen kann.