Обяснение за грешката
Непосредствената причина за съобщението за грешка е, че всяко изрично JOIN
свързва по-силно от запетая (,
), което иначе е еквивалентно на CROSS JOIN
, но (по документация
):
Удебелен акцентът е мой.
Това е причината за вашата грешка. Вие можете поправи го:
FROM appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...
Но това не беше единственият проблем. Продължете да четете.
Някой може да възрази, че Postgres трябва да види това LATERAL
има смисъл само във връзка с таблицата вляво. Но това не е така.
Предположение
Добавих псевдоними на таблици и квалифицирах всички имена на колони според подозрението. Докато се занимавах с това, опростих препратките към JSON и отрязах някои шумове. Тази заявка все още е неправилна :
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
Необработена заявка
Въз основа на горното и някои други предположения, решението може да бъде преброяването да се извърши в подзаявка:
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;
Тъй като имате нужда само от броя, преобразувах вашия LATERAL
присъединете към корелирана подзаявка, като по този начин избягвате различните проблеми, произтичащи от комбинирането на множество 1:n съединявания. Още:
- Каква е разликата между LATERAL JOIN и подзаявка в PostgreSQL?
- Две SQL ЛЕВИ СЪЕДИНЕНИЯ дават неправилен резултат
Виетрябвате за да избегнете правилно идентификаторите, използвайте подготвен израз и предавайте стойности като ценности. Не свързвайте стойности в низа на заявката. Това е покана за случайни грешки или SQL инжектиране атаки. Скорошен пример за PHP: