View a markdown version of this page

DENGAN klausa - Amazon Redshift

Amazon Redshift tidak akan lagi mendukung penggunaan Python UDF setelah 30 Juni 2026. Kami akan mulai menegakkannya secara bertahap. Untuk informasi lebih lanjut tentang detail opsi akhir masa pakai dan migrasi Python, lihat posting blog yang diterbitkan pada 30 Juni 2025.

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

DENGAN klausa

Klausa WITH adalah klausa opsional yang mendahului daftar SELECT dalam kueri. Klausa WITH mendefinisikan satu atau lebih common_table_expression. Setiap ekspresi tabel umum (CTE) mendefinisikan tabel sementara, yang mirip dengan definisi tampilan. Anda dapat mereferensikan tabel sementara ini dalam klausa FROM. Mereka hanya digunakan saat kueri tempat mereka berjalan. Setiap CTE dalam klausa WITH menentukan nama tabel, daftar opsional nama kolom, dan ekspresi kueri yang mengevaluasi ke tabel (pernyataan SELECT). Ketika Anda mereferensikan nama tabel sementara dalam klausa FROM dari ekspresi kueri yang sama yang mendefinisikannya, CTE bersifat rekursif.

WITH klausa subquery adalah cara yang efisien untuk mendefinisikan tabel yang dapat digunakan sepanjang eksekusi kueri tunggal. Dalam semua kasus, hasil yang sama dapat dicapai dengan menggunakan subquery di badan utama pernyataan SELECT, tetapi dengan subquery klausa mungkin lebih sederhana untuk ditulis dan dibaca. Jika memungkinkan, subkueri klausa WITH yang direferensikan beberapa kali dioptimalkan sebagai subexpresi umum; yaitu, dimungkinkan untuk mengevaluasi subkueri WITH sekali dan menggunakan kembali hasilnya. (Perhatikan bahwa subekpresi umum tidak terbatas pada yang didefinisikan dalam klausa WITH.)

Sintaksis

[ WITH [RECURSIVE] common_table_expression [, common_table_expression , ...] ]

dimana common_table_expression dapat berupa non-rekursif atau rekursif. Berikut ini adalah bentuk non-rekursif:

CTE_table_name [ ( column_name [, ...] ) ] AS ( query )

Berikut ini adalah bentuk rekursif dari common _table_expression:

CTE_table_name (column_name [, ...] ) AS ( recursive_query )

Parameter

REKURSIF

Kata kunci yang mengidentifikasi query sebagai CTE rekursif. Kata kunci ini diperlukan jika common_table_expression yang didefinisikan dalam klausa WITH bersifat rekursif. Anda hanya dapat menentukan kata kunci RECURSIVE sekali, segera mengikuti kata kunci WITH, bahkan ketika klausa WITH berisi beberapa CTE rekursif. Secara umum, CTE rekursif adalah subquery UNION ALL dengan dua bagian.

Ekspresi tabel_umum

Mendefinisikan tabel sementara yang dapat Anda referensikan Klausa FROM dan hanya digunakan selama pelaksanaan kueri yang menjadi miliknya.

Nama Tabel_CTE

Nama unik untuk tabel sementara yang mendefinisikan hasil subquery klausa WITH. Anda tidak dapat menggunakan nama duplikat dalam satu klausa WITH. Setiap subquery harus diberi nama tabel yang dapat direferensikan diKlausa FROM.

nama_kolom

Daftar nama kolom keluaran untuk subquery klausa WITH, dipisahkan oleh koma. Jumlah nama kolom yang ditentukan harus sama dengan atau kurang dari jumlah kolom yang ditentukan oleh subquery. Untuk CTE yang non-rekursif, klausa column _name bersifat opsional. Untuk CTE rekursif, daftar column_ name diperlukan.

query

Setiap kueri SELECT yang didukung Amazon Redshift. Lihat SELECT.

rekursif_query

Kueri UNION ALL yang terdiri dari dua subquery SELECT:

  • Subkueri SELECT pertama tidak memiliki referensi rekursif ke CTE_table_name yang sama. Ini mengembalikan set hasil yang merupakan benih awal dari rekursi. Bagian ini disebut anggota awal atau anggota benih.

  • Subquery SELECT kedua mereferensikan CTE_table_name yang sama dalam klausa FROM-nya. Ini disebut anggota rekursif. Recursive_query berisi kondisi WHERE untuk mengakhiri recursive_query.

Catatan penggunaan

Anda dapat menggunakan klausa WITH dalam pernyataan SQL berikut:

  • SELECT

  • PILIH KE

  • CREATE TABLE AS

  • CREATE VIEW

  • MENYATAKAN

  • EXPLAIN

  • MASUKKAN KE... PILIH

  • MEMPERSIAPKAN

  • UPDATE (dalam subkueri klausa WHERE. Anda tidak dapat mendefinisikan CTE rekursif di subquery. CTE rekursif harus mendahului klausa UPDATE.)

  • DELETE

Jika klausa FROM dari query yang berisi klausa WITH tidak mereferensikan salah satu tabel yang ditentukan oleh klausa WITH, klausa WITH diabaikan dan query berjalan seperti biasa.

Tabel yang ditentukan oleh subkueri klausa WITH dapat direferensikan hanya dalam lingkup query SELECT yang dimulai klausa WITH. Misalnya, Anda dapat mereferensikan tabel tersebut dalam klausa FROM dari subkueri dalam daftar SELECT, klausa WHERE, atau klausa HAVING. Anda tidak dapat menggunakan klausa WITH dalam subquery dan mereferensikan tabelnya dalam klausa FROM dari query utama atau subkueri lain. Pola kueri ini menghasilkan pesan kesalahan dari formulir relation table_name doesn't exist untuk tabel klausa WITH.

Anda tidak dapat menentukan klausa WITH lain di dalam subquery klausa WITH.

Anda tidak dapat membuat referensi ke tabel yang ditentukan oleh subkueri klausa WITH. Misalnya, kueri berikut mengembalikan kesalahan karena referensi maju ke tabel W2 dalam definisi tabel W1:

with w1 as (select * from w2), w2 as (select * from w1) select * from sales; ERROR: relation "w2" does not exist

Subquery klausa WITH mungkin tidak terdiri dari pernyataan SELECT INTO; namun, Anda dapat menggunakan klausa WITH dalam pernyataan SELECT INTO.

Ekspresi tabel umum rekursif

Sebuah ekspresi tabel umum rekursif (CTE) adalah CTE yang mereferensikan dirinya sendiri. CTE rekursif berguna dalam menanyakan data hierarkis, seperti bagan organisasi yang menunjukkan hubungan pelaporan antara karyawan dan manajer. Lihat Contoh: CTE Rekursif.

Penggunaan umum lainnya adalah daftar bahan bertingkat, ketika suatu produk terdiri dari banyak komponen dan setiap komponen itu sendiri juga terdiri dari komponen atau subrakitan lain.

Pastikan untuk membatasi kedalaman rekursi dengan memasukkan klausa WHERE di subquery SELECT kedua dari kueri rekursif. Sebagai contoh, lihat Contoh: CTE Rekursif. Jika tidak, kesalahan dapat terjadi mirip dengan berikut ini:

  • Recursive CTE out of working buffers.

  • Exceeded recursive CTE max rows limit, please add correct CTE termination predicates or change the max_recursion_rows parameter.

catatan

max_recursion_rowsadalah parameter yang mengatur jumlah baris maksimum yang dapat dikembalikan oleh CTE rekursif untuk mencegah loop rekursi tak terbatas. Kami menyarankan agar tidak mengubah ini ke nilai yang lebih besar dari default. Ini mencegah masalah rekursi tak terbatas dalam kueri Anda mengambil ruang yang berlebihan di cluster Anda.

Anda dapat menentukan urutan pengurutan dan membatasi hasil CTE rekursif. Anda dapat menyertakan opsi grup berdasarkan dan berbeda pada hasil akhir dari CTE rekursif.

Anda tidak dapat menentukan klausa WITH RECURSIVE di dalam subquery. Anggota recursive_query tidak dapat menyertakan klausa order by atau limit.

Contoh

Contoh berikut menunjukkan kasus paling sederhana dari kueri yang berisi klausa WITH. Kueri WITH bernama VENUECOPY memilih semua baris dari tabel VENUE. Kueri utama pada gilirannya memilih semua baris dari VENUECOPY. Tabel VENUECOPY hanya ada selama kueri ini.

with venuecopy as (select * from venue) select * from venuecopy order by 1 limit 10;
venueid | venuename | venuecity | venuestate | venueseats ---------+----------------------------+-----------------+------------+------------ 1 | Toyota Park | Bridgeview | IL | 0 2 | Columbus Crew Stadium | Columbus | OH | 0 3 | RFK Stadium | Washington | DC | 0 4 | CommunityAmerica Ballpark | Kansas City | KS | 0 5 | Gillette Stadium | Foxborough | MA | 68756 6 | New York Giants Stadium | East Rutherford | NJ | 80242 7 | BMO Field | Toronto | ON | 0 8 | The Home Depot Center | Carson | CA | 0 9 | Dick's Sporting Goods Park | Commerce City | CO | 0 v 10 | Pizza Hut Park | Frisco | TX | 0 (10 rows)

Contoh berikut menunjukkan klausa WITH yang menghasilkan dua tabel, bernama VENUE_SALES dan TOP_VENUES. Tabel kueri WITH kedua memilih dari yang pertama. Pada gilirannya, klausa WHERE dari blok kueri utama berisi subquery yang membatasi tabel TOP_VENUES.

with venue_sales as (select venuename, venuecity, sum(pricepaid) as venuename_sales from sales, venue, event where venue.venueid=event.venueid and event.eventid=sales.eventid group by venuename, venuecity), top_venues as (select venuename from venue_sales where venuename_sales > 800000) select venuename, venuecity, venuestate, sum(qtysold) as venue_qty, sum(pricepaid) as venue_sales from sales, venue, event where venue.venueid=event.venueid and event.eventid=sales.eventid and venuename in(select venuename from top_venues) group by venuename, venuecity, venuestate order by venuename;
venuename | venuecity | venuestate | venue_qty | venue_sales ------------------------+---------------+------------+-----------+------------- August Wilson Theatre | New York City | NY | 3187 | 1032156.00 Biltmore Theatre | New York City | NY | 2629 | 828981.00 Charles Playhouse | Boston | MA | 2502 | 857031.00 Ethel Barrymore Theatre | New York City | NY | 2828 | 891172.00 Eugene O'Neill Theatre | New York City | NY | 2488 | 828950.00 Greek Theatre | Los Angeles | CA | 2445 | 838918.00 Helen Hayes Theatre | New York City | NY | 2948 | 978765.00 Hilton Theatre | New York City | NY | 2999 | 885686.00 Imperial Theatre | New York City | NY | 2702 | 877993.00 Lunt-Fontanne Theatre | New York City | NY | 3326 | 1115182.00 Majestic Theatre | New York City | NY | 2549 | 894275.00 Nederlander Theatre | New York City | NY | 2934 | 936312.00 Pasadena Playhouse | Pasadena | CA | 2739 | 820435.00 Winter Garden Theatre | New York City | NY | 2838 | 939257.00 (14 rows)

Dua contoh berikut menunjukkan aturan untuk ruang lingkup referensi tabel berdasarkan subquery klausa WITH. Kueri pertama berjalan, tetapi yang kedua gagal dengan kesalahan yang diharapkan. Kueri pertama memiliki subquery klausa WITH di dalam daftar SELECT dari query utama. Tabel yang ditentukan oleh klausa WITH (HOLIDAYS) direferensikan dalam klausa FROM subkueri dalam daftar SELECT:

select caldate, sum(pricepaid) as daysales, (with holidays as (select * from date where holiday ='t') select sum(pricepaid) from sales join holidays on sales.dateid=holidays.dateid where caldate='2008-12-25') as dec25sales from sales join date on sales.dateid=date.dateid where caldate in('2008-12-25','2008-12-31') group by caldate order by caldate; caldate | daysales | dec25sales -----------+----------+------------ 2008-12-25 | 70402.00 | 70402.00 2008-12-31 | 12678.00 | 70402.00 (2 rows)

Kueri kedua gagal karena mencoba untuk mereferensikan tabel HOLIDAYS di kueri utama serta di subkueri daftar SELECT. Referensi kueri utama berada di luar cakupan.

select caldate, sum(pricepaid) as daysales, (with holidays as (select * from date where holiday ='t') select sum(pricepaid) from sales join holidays on sales.dateid=holidays.dateid where caldate='2008-12-25') as dec25sales from sales join holidays on sales.dateid=holidays.dateid where caldate in('2008-12-25','2008-12-31') group by caldate order by caldate; ERROR: relation "holidays" does not exist

Contoh: CTE Rekursif

Berikut ini adalah contoh CTE rekursif yang mengembalikan karyawan yang melaporkan secara langsung atau tidak langsung kepada John. Kueri rekursif berisi klausa WHERE untuk membatasi kedalaman rekursi kurang dari 4 level.

--create and populate the sample table create table employee ( id int, name varchar (20), manager_id int ); insert into employee(id, name, manager_id) values (100, 'Carlos', null), (101, 'John', 100), (102, 'Jorge', 101), (103, 'Kwaku', 101), (110, 'Liu', 101), (106, 'Mateo', 102), (110, 'Nikki', 103), (104, 'Paulo', 103), (105, 'Richard', 103), (120, 'Saanvi', 104), (200, 'Shirley', 104), (201, 'Sofía', 102), (205, 'Zhang', 104); --run the recursive query with recursive john_org(id, name, manager_id, level) as ( select id, name, manager_id, 1 as level from employee where name = 'John' union all select e.id, e.name, e.manager_id, level + 1 as next_level from employee e, john_org j where e.manager_id = j.id and level < 4 ) select distinct id, name, manager_id from john_org order by manager_id;

Berikut ini adalah hasil dari query.

id name manager_id ------+-----------+-------------- 101 John 100 102 Jorge 101 103 Kwaku 101 110 Liu 101 201 Sofía 102 106 Mateo 102 110 Nikki 103 104 Paulo 103 105 Richard 103 120 Saanvi 104 200 Shirley 104 205 Zhang 104

Berikut ini adalah bagan organisasi untuk departemen John.

Diagram bagan organisasi untuk departemen John.