Chciałbym „zadeklarować”, czym jest efektywnie wiele tabel TEMP przy użyciu instrukcji WITH. Zapytanie, które próbuję wykonać, wygląda następująco:
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
Przeczytałem dokumentację PostgreSQL i zbadałem użycie wielu WITH
instrukcji i nie mogłem znaleźć odpowiedzi.
with
instrukcją, a inne po niej. Nie jestem pewien co do postgres, ale to normalna składnia z serwerem Oracle i sqlERROR: syntax error at or near "WITH"
dla przecinka iERROR: syntax error at or near ";"
dla średnika.Odpowiedzi:
Zgodnie z innymi komentarzami drugie wyrażenie Common Table Expression [CTE] jest poprzedzone przecinkiem, a nie instrukcją WITH, więc
WITH cte1 AS (SELECT...) , cte2 AS (SELECT...) SELECT * FROM cte1 c1 INNER JOIN cte2 c2 ON ........
Jeśli chodzi o twoje rzeczywiste zapytanie, ta składnia powinna działać w PostgreSql, Oracle i sql-server, cóż, później zwykle będziesz postępować
WITH
ze średnikiem (;WTIH
), ale to dlatego, że zazwyczaj ludzie z serwera sql (włącznie ze mną) nie kończą poprzednie oświadczenia, które należy zakończyć przed zdefiniowaniem CTE ...Zwróć jednak uwagę, że wystąpił drugi problem ze składnią w odniesieniu do
WHERE
instrukcji.WHERE date IN table_2
jest nieprawidłowa, ponieważ w rzeczywistości nigdy nie odwołujesz się do wartości / kolumny z tabeli_2. WolęINNER JOIN
nadIN
lubExists
tak tutaj jest składnia, który powinien działać zJOIN
: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 ;
Jeśli chcesz zachować to, co miałeś, co zwykle EXISTS byłoby lepsze niż IN, ale aby użyć IN, potrzebujesz rzeczywistej instrukcji SELECT w miejscu gdzie.
SELECT * FROM table_1 t1 WHERE t1.date IN (SELECT date FROM table_2);
IN jest bardzo problematyczne, kiedy
date
potencjalnie może być,NULL
więc jeśli nie chcesz używaćJOIN
, to proponujęEXISTS
. Następująco:SELECT * FROM table_1 t1 WHERE EXISTS (SELECT * FROM table_2 t2 WHERE t2.date = t1.date);
źródło
Możesz również połączyć swoje wyniki za pomocą instrukcji WITH. Na przykład:
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;
źródło