Vysvětlení chyby
Bezprostřední příčinou chybové zprávy je jakákoli explicitní JOIN
vazba je silnější než čárka (,
), což je jinak ekvivalentní CROSS JOIN
, ale (podle dokumentace
):
Tučné důraz můj.
Toto je příčina vaší chyby. Mohli byste opravit:
FROM appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...
To ale nebyl jediný problém. Pokračujte ve čtení.
Někdo by mohl namítnout, že Postgres by měl vidět LATERAL
má smysl pouze ve spojení s tabulkou vlevo. Ale není tomu tak.
Předpoklad
Přidal jsem aliasy tabulek a kvalifikoval jsem všechny názvy sloupců jako podezřelé. Během toho jsem zjednodušil reference JSON a ořezal nějaký šum. Tento dotaz je stále nesprávný :
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
Nezpracovaný dotaz
Na základě výše uvedeného a některých dalších předpokladů by řešením mohlo být provedení počítání v dílčím dotazu:
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;
Protože potřebujete pouze počet, převedl jsem váš LATERAL
spojit do korelovaného poddotazu, čímž se vyhnete různým problémům vyplývajícím z více kombinovaných spojení 1:n. Více:
- Jaký je rozdíl mezi LATERAL JOIN a dílčím dotazem v PostgreSQL?
- DVA LEVÉ PŘIPOJENÍ SQL způsobit nesprávný výsledek
potřebujete aby byly identifikátory escape správně, použijte připravený příkaz a předat hodnoty jako hodnoty. Nezřetězujte hodnoty do řetězce dotazu. To je pozvánka na náhodné chyby nebo vložení SQL útoky. Nedávný příklad pro PHP: