sql >> Database teknologi >  >> RDS >> PostgreSQL

ugyldig reference til FROM-klausulindtastning for tabel i Postgres-forespørgsel

Forklaring på fejlen

Den umiddelbare årsag til fejlmeddelelsen er, at enhver eksplicit JOIN binder stærkere end et komma (, ) som ellers svarer til en CROSS JOIN , men (pr. dokumentation ):

Fed fremhæve mine.
Dette er årsagen til din fejl. Du kunne rette det:

FROM  appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...

Men det var ikke det eneste problem. Fortsæt med at læse.

Man kan hævde, at Postgres burde se den LATERAL giver kun mening i forbindelse med tabellen til venstre. Men sådan er det ikke.

Antagelse

Jeg tilføjede tabelaliasser og tabelkvalificerede alle kolonnenavne som mistænkt. Mens jeg var i gang, forenklede jeg JSON-referencerne og trimmede noget støj. Denne forespørgsel er stadig forkert :

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

Rå forespørgsel

Baseret på ovenstående og nogle flere antagelser kunne løsningen være at foretage optællingen i en underforespørgsel:

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;

Da du kun har brug for optællingen, konverterede jeg din LATERAL join ind i en korreleret underforespørgsel, og undgår derved de forskellige problemer, der opstår fra flere 1:n joins kombineret. Mere:

Du har brug for for at undslippe identifikatorer korrekt, brug en forberedt erklæring og videregive værdier som værdier. Lad være med at sammenkæde værdier i forespørgselsstrengen. Det er en invitation til tilfældige fejl eller SQL-injektion angreb. Seneste eksempel for PHP:




  1. PL/SQL:hvordan beder jeg brugerinput i en procedure?

  2. filtrer en søgning med alternativknappen PHP SQL

  3. Hvordan genstarter man en ekstern MySQL-server, der kører på Ubuntu linux?

  4. Django admin MySQL langsom INNER JOIN