sql >> データベース >  >> RDS >> PostgreSQL

PostgresクエリのテーブルのFROM句エントリへの無効な参照

    エラーの説明

    エラーメッセージの直接の原因は、明示的な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の最近の例:




    1. 組み込みのストップワードリストを、LAMP上のMySQLのフルテキストストップワードのユーザー定義リストで上書きするにはどうすればよいですか?

    2. MySQL:左結合と右結合の結合

    3. RLIKEがMariaDBでどのように機能するか

    4. XAMPPはWindows7の起動時に自動的に起動します