sql >> Base de Datos >  >> RDS >> PostgreSQL

referencia no válida a la entrada de la cláusula FROM para la tabla en la consulta de Postgres

Explicación del error

La causa inmediata del mensaje de error es que cualquier JOIN explícito se une más fuerte que una coma (, ) que por lo demás es equivalente a CROSS JOIN , pero (por documentación ):

Negrita énfasis mío.
Esta es la causa de su error. podrías arreglarlo:

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

Pero ese no fue el único problema. Sigue leyendo.

Se podría argumentar que Postgres debería ver que LATERAL sólo tiene sentido en relación con la tabla de la izquierda. Pero eso no es así.

Suposición

Agregué alias de tabla y califiqué en la tabla todos los nombres de columna como sospechosos. Mientras lo hacía, simplifiqué las referencias JSON y recorté algo de ruido. Esta consulta todavía es incorrecta :

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

Consulta sin procesar

En base a lo anterior y algunas suposiciones más, la solución podría ser hacer el conteo en una subconsulta:

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;

Como solo necesitas el conteo, convertí tu LATERAL join en una subconsulta correlacionada, evitando así los diversos problemas que surgen de múltiples uniones 1:n combinadas. Más:

Usted necesita para escapar de los identificadores correctamente, use una declaración preparada y pasar valores como valores. No concatene valores en la cadena de consulta. Esa es una invitación para errores aleatorios o inyección SQL ataques Ejemplo reciente para PHP: