Eu gostaria de "declarar" o que são efetivamente várias tabelas TEMP usando a instrução WITH. A consulta que estou tentando executar segue as linhas de:
WITH table_1 AS (
SELECT GENERATE_SERIES('2012-06-29', '2012-07-03', '1 day'::INTERVAL) AS date
)
WITH table_2 AS (
SELECT GENERATE_SERIES('2012-06-30', '2012-07-13', '1 day'::INTERVAL) AS date
)
SELECT * FROM table_1
WHERE date IN table_2
Eu li a documentação do PostgreSQL e pesquisei o uso de várias WITH
instruções e não consegui encontrar uma resposta.
with
afirmação, qualquer outra depois. Não tenho certeza sobre o postgres, mas essa é a sintaxe normal com Oracle e sql serverERROR: syntax error at or near "WITH"
para a vírgula eERROR: syntax error at or near ";"
para o ponto e vírgula.Respostas:
De acordo com os outros comentários, a segunda Expressão de Tabela Comum [CTE] é precedida por uma vírgula, não por uma instrução WITH, portanto
WITH cte1 AS (SELECT...) , cte2 AS (SELECT...) SELECT * FROM cte1 c1 INNER JOIN cte2 c2 ON ........
Em termos de sua consulta real, esta sintaxe deve funcionar em PostgreSql, Oracle e sql-server, bem o último, normalmente, você continuará
WITH
com um ponto-e-vírgula (;WTIH
), mas isso é porque normalmente o pessoal do sql-server (eu incluído) não termina declarações anteriores que precisam ser encerradas antes de um CTE ser definido ...Observe, entretanto, que você teve um segundo problema de sintaxe em relação à sua
WHERE
instrução.WHERE date IN table_2
não é válido porque você nunca faz referência a um valor / coluna da tabela_2. Eu prefiroINNER JOIN
maisIN
ouExists
menos aqui está uma sintaxe que deve funcionar com umJOIN
:WITH table_1 AS ( SELECT GENERATE_SERIES('2012-06-29', '2012-07-03', '1 day'::INTERVAL) AS date ) , table_2 AS ( SELECT GENERATE_SERIES('2012-06-30', '2012-07-13', '1 day'::INTERVAL) AS date ) SELECT * FROM table_1 t1 INNER JOIN table_2 t2 ON t1.date = t2.date ;
Se você quiser manter a forma que você tinha, que normalmente EXISTS seria melhor do que IN, mas para usar IN você precisa de uma instrução SELECT real em seu where.
SELECT * FROM table_1 t1 WHERE t1.date IN (SELECT date FROM table_2);
IN é muito problemático quando
date
potencialmente poderia serNULL
se você não quiser usar um,JOIN
então eu sugiroEXISTS
. Do seguinte modo:SELECT * FROM table_1 t1 WHERE EXISTS (SELECT * FROM table_2 t2 WHERE t2.date = t1.date);
fonte
Você também pode encadear seus resultados usando a instrução WITH. Por exemplo:
WITH tab1 as (Your SQL statement), tab2 as ( SELECT ... FROM tab1 WHERE your filter), tab3 as ( SELECT ... FROM tab2 WHERE your filter) SELECT * FROM tab3;
fonte