Explicação do erro
A causa imediata para a mensagem de erro é que qualquer
JOIN
explícito liga mais forte que uma vírgula (,
) que é equivalente a um CROSS JOIN
, mas (por documentação
):Negrito ênfase minha.
Esta é a causa do seu erro. Você poderia consertá-lo:
FROM appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...
Mas esse não foi o único problema. Continue lendo.
Pode-se argumentar que o Postgres deveria ver que
LATERAL
só faz sentido em conexão com a tabela à esquerda. Mas não é assim. Suposição
Adicionei aliases de tabela e qualifiquei todos os nomes de coluna como suspeitos. Enquanto isso, simplifiquei as referências JSON e reduzi alguns ruídos. Esta consulta ainda está incorreta :
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 bruta
Com base no acima e em mais algumas suposições, a solução poderia ser fazer a contagem em uma 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 você só precisa da contagem, converti seu
LATERAL
join em uma subconsulta correlacionada, evitando assim os vários problemas decorrentes de várias junções 1:n combinadas. Mais:- Qual é a diferença entre LATERAL JOIN e uma subconsulta no PostgreSQL?
- Dois SQL LEFT JOINS produzir resultado incorreto
Você precisa para escapar dos identificadores corretamente, use uma instrução preparada e passar valores como valores. Não concatene valores na string de consulta. Isso é um convite para erros aleatórios ou injeção de SQL ataques. Exemplo recente para PHP: