エラーの説明
エラーメッセージの直接の原因は、明示的な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結合の組み合わせから生じるさまざまな問題を回避します。詳細:
必要 識別子を適切にエスケープするには、プリペアドステートメントを使用します 値を渡します 値として。値をクエリ文字列に連結しないでください。これは、ランダムエラーまたはSQLインジェクションへの招待です。 攻撃。 PHPの最近の例: