Förklaring till felet
Den omedelbara orsaken till felmeddelandet är att någon explicit JOIN
binder starkare än ett kommatecken (,
) som annars motsvarar en CROSS JOIN
, men (per dokumentation
):
Fet betoning min.
Detta är orsaken till ditt fel. Du kunde fixa det:
FROM appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...
Men det var inte det enda problemet. Fortsätt läsa.
Man kan hävda att Postgres borde se den LATERAL
är bara vettigt i samband med tabellen till vänster. Men så är det inte.
Antagande
Jag lade till tabellalias och tabellkvalificerade alla kolumnnamn som misstänkt. Medan jag var på gång förenklade jag JSON-referenserna och trimmade lite brus. Den här frågan är fortfarande felaktig :
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
Raw query
Baserat på ovanstående och några fler antaganden kan lösningen vara att räkna i en underfråga:
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;
Eftersom du bara behöver räkningen konverterade jag din LATERAL
join till en korrelerad delfråga, och undviker därigenom de olika problemen som uppstår från kombinerade 1:n-kopplingar. Mer:
- Vad är skillnaden mellan LATERAL JOIN och en underfråga i PostgreSQL?
- Två SQL LEFT JOINS ger felaktigt resultat
Du behöver för att undvika identifierare korrekt, använd en förberedd sats och skicka värden som värden. Sammanfoga inte värden i frågesträngen. Det är en inbjudan för slumpmässiga fel eller SQL-injektion attacker. Senaste exempel för PHP: