Uczę się PostgreSQL i próbuję wymyślić, jak utworzyć tymczasową tabelę lub WITH
deklarację, której można użyć zamiast zwykłej tabeli do celów debugowania.
Przejrzałem dokumentację CREATE TABLE i mówi, że VALUES
można ją wykorzystać jako zapytanie, ale nie podaje żadnego przykładu; dokumentacja VALUES
klauzuli w niej zawartej również nie ma przykładu?
Napisałem więc prosty test w następujący sposób:
DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup (
key integer,
val numeric
) AS
VALUES (0,-99999), (1,100);
Ale PostgreSQL (9.3) narzeka
błąd składniowy przy „AS” lub w jego pobliżu
Moje pytania to:
Jak mogę naprawić powyższe stwierdzenie?
Jak mogę go dostosować do użycia w
WITH block
?
Z góry dziękuję.
postgresql
syntax
tinlyx
źródło
źródło
Odpowiedzi:
EDYCJA: Pozostawiam oryginalną zaakceptowaną odpowiedź taką, jaka jest, ale pamiętaj, że poniższa edycja, sugerowana przez a_horse_w_no_name, jest preferowaną metodą tworzenia tabeli tymczasowej przy użyciu VALUES.
Jeśli chcesz tylko wybrać jedną z wartości, zamiast tworzyć tabelę i wstawiać do niej, możesz zrobić coś takiego:
Aby faktycznie utworzyć tymczasowy stół w podobny sposób, użyj:
EDYCJA: Jak wskazano przez a_horse_with_no_name, w dokumentach stwierdza, że
CREATE TABLE AS...
jest funkcjonalnie podobnySELECT INTO ...
, ale że ten pierwszy jest nadzbiorem drugiego i którySELECT INTO
jest używany w plpgslq do przypisywania wartości do zmiennej tymczasowej - więc nie powiodłaby się ta walizka. Dlatego, chociaż powyższe przykłady dotyczą zwykłego SQL,CREATE TABLE
forma powinna być preferowana.Uwaga: również z komentarzy autorstwa_nazwa_nazwy_nazwa oraz w pierwotnym pytaniu PO, obejmuje to rzutowanie na prawidłowe typy danych na liście wartości i użycie instrukcji CTE (Z).
Ponadto, jak wskazano w odpowiedzi Evana Carrola, zapytanie CTE jest ogrodzeniem optymalizacyjnym , tj. CTE jest zawsze zmaterializowane. Istnieje wiele dobrych powodów, aby używać CTE, ale może być dość znaczący spadek wydajności, jeśli nie zostanie zastosowany ostrożnie. Istnieje jednak wiele przypadków, w których płot optymalizacyjny może rzeczywiście poprawić wydajność, więc należy o tym pamiętać, a nie ślepo unikać.
źródło
WHERE ST_Intersects(geom, (SELECT geom FROM sometable)
lubWHERE ST_Intersects(geom, ST_Buffer(anothergeom, 10)
często planista zapytań nie używa indeksu przestrzennego, ponieważ kolumna geom nie jest już możliwa do sargowania. Jeśli utworzysz obszar zainteresowania w początkowej CTE, ten problem zniknie. Jest to również bardzo wygodne, jeśli chcesz używać tego samego aoi w wielu innych wyrażeniach w tym samym zapytaniu, co nie jest rzadkością w kontekście GIS.create table as
potrzebuje instrukcji select:Możesz także ponownie napisać to, aby użyć CTE:
źródło
Problemem są typy danych. Jeśli je usuniesz, instrukcja będzie działać:
Możesz zdefiniować typy, rzutując wartości z pierwszego wiersza:
źródło
Naprawdę nie musisz tworzyć tabeli ani używać CTE, jeśli wszystko, czego potrzebujesz, to użyć kilku wartości w zapytaniach. Możesz je wstawić:
Następnie możesz uzyskać produkt kartezjański z
CROSS JOIN
(gdzie drugą relacją może być oczywiście zwykły stół, widok itp.). na przykład:co daje:
Lub
JOIN
wartości z inną relacją (która może być zwykłą tabelą, widokiem itp.), Np .:co daje:
źródło
Najpierw zawsze używaj standardowego
CREATE TABLE AS
,SELECT INTO
jak sugerowano w innych odpowiedziach, jest to przestarzała składnia od ponad dekady. Możesz używaćCREATE TABLE AS
z CTEChociaż wiele odpowiedzi tutaj sugeruje użycie CTE, nie jest to preferowane. W rzeczywistości jest to nieco wolniejsze. Po prostu zawiń w stół.
Jeśli musisz napisać instrukcję select, możesz to zrobić (i nie potrzebujesz CTE).
CTE w PostgreSQL wymusza materializację. To płot optymalizacyjny. Z tego powodu generalnie nie jest dobrym pomysłem stosowanie ich w dowolnym miejscu, z wyjątkiem sytuacji, gdy rozumiesz koszty i wiesz, że zapewnia to poprawę wydajności. Możesz zobaczyć tutaj spowolnienie, na przykład
źródło
źródło