PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Czy zapytania typu SELECT są jedynym typem, który można zagnieżdżać?

Odpowiedź podstawowa

Istnieją CTE (Typowe wyrażenia tabel) w Postgres (jak w każdym większym współczesnym RDBMS z wyjątkiem MySQL). Od wersji 9.1, która zawiera CTE modyfikujące dane. Można je „zagnieździć”.
Aktualizacja:MySQL 8.0 w końcu dodaje CTE.

W przeciwieństwie do podzapytań CTE stanowią bariery optymalizacji. Planer zapytań nie może wstawiać trywialnych poleceń do głównego polecenia ani zmieniać kolejności łączeń między głównym zapytaniem a CTE. To samo jest możliwe z podzapytaniami. Może być (bardzo) dobra lub (bardzo) zła dla wydajności, to zależy.
Tak czy inaczej, CTE wymagają nieco więcej narzutów (koszt wydajności) niż podzapytania.
Aktualizacja:Postgres 12 może wreszcie wbudować zwykłe CTE w głównym zapytaniu.

Szczegóły, o które nie prosiłeś

Twoje pytanie jest bardzo proste, powyższe prawdopodobnie wystarczy, aby odpowiedzieć. Ale dodam trochę dla zaawansowanych użytkowników (i przykład kodu, aby pokazać składnię).

Wszystkie CTE zapytania są oparte na tej samej migawce bazy danych. Następne CTE może ponownie wykorzystać wyjście poprzednich CTE (wewnętrzne tabele tymczasowe), ale wpływ na tabele bazowe jest niewidoczny dla innych CTE. Sekwencja wielu CTE jest dowolna chyba, że coś jest zwracane z RETURNING klauzula INSERT , UPDATE , DELETE - nieistotne dla SELECT , ponieważ niczego nie zmienia i po prostu odczytuje zrzut obrazu.

Może to mieć subtelne efekty z wieloma aktualizacjami, które miałyby wpływ na ten sam wiersz. Tylko jeden aktualizacja może mieć wpływ na każdy wiersz. Na który z nich ma wpływ kolejność CTE.

Spróbuj przewidzieć wynik:

CREATE TEMP TABLE t (t_id int, txt text);
INSERT INTO t VALUES (1, 'foo'), (2, 'bar'), (3, 'baz');

WITH sel AS (SELECT * FROM t)
   , up1 AS (UPDATE t SET txt = txt || '1' WHERE t_id = 1 RETURNING *)
   , up2 AS (UPDATE t SET txt = t.txt || '2'
             FROM   up1
             WHERE  up1.t_id = t.t_id
             RETURNING t.*)
   , ins AS (INSERT INTO t VALUES (4, 'bamm'))
   , up3 AS (UPDATE t SET txt = txt || '3' RETURNING *)
SELECT 'sel' AS source, * FROM sel
UNION ALL
SELECT 'up1' AS source, * FROM up1
UNION ALL
SELECT 'up2' AS source, * FROM up2
UNION ALL
SELECT 'up3' AS source, * FROM up3
UNION ALL
SELECT 't'   AS source, * FROM t;

Skrzypce SQL

Nie bądź rozczarowany, wątpię, czy jest tu wielu, którzy mogliby to zrobić. :)
Istota tego:unikaj sprzeczne polecenia w CTE.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mapowanie hibernacji między enum PostgreSQL i enum w Javie

  2. Rekurencyjne CTE łączą pola z rodzicami z dowolnego punktu

  3. Jak dostosować plik konfiguracyjny oficjalnego obrazu Docker PostgreSQL?

  4. PostgreSQL:Wszechstronna INSERT

  5. Przyrostowa kopia zapasowa PostgreSQL i odzyskiwanie do określonego momentu