Uitleg voor de fout
De directe oorzaak van de foutmelding is dat elke expliciete JOIN
bindt sterker dan een komma (,
) wat anders gelijk is aan een CROSS JOIN
, maar (per documentatie
):
Vet nadruk van mij.
Dit is de oorzaak van je fout. Je zou repareer het:
FROM appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...
Maar dat was niet het enige probleem. Blijf lezen.
Je zou kunnen stellen dat Postgres zou moeten zien dat LATERAL
heeft alleen zin in verband met de tabel links. Maar dat is niet zo.
Aanname
Ik voegde tabelaliassen toe en kwalificeerde alle kolomnamen als verdacht. Terwijl ik bezig was, heb ik de JSON-referenties vereenvoudigd en wat ruis bijgesneden. Deze zoekopdracht is nog steeds onjuist :
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
Onbewerkte zoekopdracht
Op basis van het bovenstaande en wat meer aannames, zou de oplossing kunnen zijn om de telling in een subquery uit te voeren:
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;
Omdat je alleen de telling nodig hebt, heb ik je LATERAL
. geconverteerd join in een gecorreleerde subquery, waardoor de verschillende problemen worden vermeden die voortvloeien uit meerdere gecombineerde 1:n-joins. Meer:
- Wat is het verschil tussen LATERAL JOIN en een subquery in PostgreSQL?
- Twee SQL LEFT JOINS produceer een onjuist resultaat
Je hebt nodig gebruik een voorbereide instructie . om identifiers correct te escapen en geef waarden door als waarden. Voeg geen waarden samen in de querytekenreeks. Dat is een uitnodiging voor willekeurige fouten of SQL-injectie aanvallen. Recent voorbeeld voor PHP: