Erklärung für den Fehler
Die unmittelbare Ursache für die Fehlermeldung ist, dass ein expliziter JOIN
bindet stärker als ein Komma (,
), was ansonsten einem CROSS JOIN
entspricht , aber (pro Dokumentation
):
Fett Hervorhebung von mir.
Das ist die Ursache Ihres Fehlers. Sie könnten beheben:
FROM appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...
Aber das war nicht das einzige Problem. Lesen Sie weiter.
Man könnte argumentieren, dass Postgres diesen LATERAL
sehen sollte nur in Verbindung mit der Tabelle links sinnvoll. Aber dem ist nicht so.
Annahme
Ich habe Tabellenaliase hinzugefügt und alle Spaltennamen wie vermutet tabellenqualifiziert. Dabei habe ich die JSON-Referenzen vereinfacht und etwas Rauschen entfernt. Diese Abfrage ist immer noch falsch :
SELECT i.data ->> 'id' AS id,
i.data ->> 'name' AS name,
i.data ->> 'curator' AS curator,
i.data -> '$isValid' AS "$isValid",
i.data -> 'customer' AS customer,
i.data -> '$createdTS' AS "$createdTS",
i.data -> '$updatedTS' AS "$updatedTS",
i.data -> '$isComplete' AS "$isComplete",
count(k.keys)::numeric AS "numProducts",
u.created_at
FROM appointment_intakes i
, jsonb_object_keys(i.data -> 'products') AS k(keys)
JOIN appointment_intake_users u ON u.appointment_intake_id = i.id
#{where_clause}
GROUP BY i.id
Rohabfrage
Basierend auf den obigen und einigen weiteren Annahmen könnte die Lösung darin bestehen, die Zählung in einer Unterabfrage durchzuführen:
SELECT i.data ->> 'id' AS id,
i.data ->> 'name' AS name,
i.data ->> 'curator' AS curator,
i.data -> '$isValid' AS "$isValid",
i.data -> 'customer' AS customer,
i.data -> '$createdTS' AS "$createdTS",
i.data -> '$updatedTS' AS "$updatedTS",
i.data -> '$isComplete' AS "$isComplete",
(SELECT count(*)::numeric
FROM jsonb_object_keys(i.data -> 'products')) AS "numProducts",
min(u.created_at) AS created_at
FROM appointment_intakes i
JOIN appointment_intake_users u ON u.appointment_intake_id = i.id
-- #{where_clause}
GROUP BY i.id;
Da du nur die Zählung benötigst, habe ich dein LATERAL
umgewandelt Join in eine korrelierte Unterabfrage, wodurch die verschiedenen Probleme vermieden werden, die sich aus der Kombination mehrerer 1:n-Joins ergeben. Mehr:
- Was ist der Unterschied zwischen LATERAL JOIN und einer Unterabfrage in PostgreSQL?
- Zwei SQL LEFT JOINS falsches Ergebnis liefern
Sie brauchen Um Bezeichner richtig zu maskieren, verwenden Sie eine vorbereitete Anweisung und Werte übergeben als Werte. Verketten Sie keine Werte in der Abfragezeichenfolge. Das ist eine Einladung für zufällige Fehler oder SQL-Injektion Anschläge. Aktuelles Beispiel für PHP: