Forklaring på fejlen
Den umiddelbare årsag til fejlmeddelelsen er, at enhver eksplicit JOIN
binder stærkere end et komma (,
) som ellers svarer til en CROSS JOIN
, men (pr. dokumentation
):
Fed fremhæve mine.
Dette er årsagen til din fejl. Du kunne rette det:
FROM appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...
Men det var ikke det eneste problem. Fortsæt med at læse.
Man kan hævde, at Postgres burde se den LATERAL
giver kun mening i forbindelse med tabellen til venstre. Men sådan er det ikke.
Antagelse
Jeg tilføjede tabelaliasser og tabelkvalificerede alle kolonnenavne som mistænkt. Mens jeg var i gang, forenklede jeg JSON-referencerne og trimmede noget støj. Denne forespørgsel er stadig forkert :
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
Rå forespørgsel
Baseret på ovenstående og nogle flere antagelser kunne løsningen være at foretage optællingen i en underforespørgsel:
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 kun har brug for optællingen, konverterede jeg din LATERAL
join ind i en korreleret underforespørgsel, og undgår derved de forskellige problemer, der opstår fra flere 1:n joins kombineret. Mere:
- Hvad er forskellen mellem LATERAL JOIN og en underforespørgsel i PostgreSQL?
- To SQL LEFT JOINS producere forkert resultat
Du har brug for for at undslippe identifikatorer korrekt, brug en forberedt erklæring og videregive værdier som værdier. Lad være med at sammenkæde værdier i forespørgselsstrengen. Det er en invitation til tilfældige fejl eller SQL-injektion angreb. Seneste eksempel for PHP: