

 Amazon Redshift tidak akan lagi mendukung pembuatan UDF Python baru mulai Patch 198. UDF Python yang ada akan terus berfungsi hingga 30 Juni 2026. Untuk informasi lebih lanjut, lihat [posting blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

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

# DENGAN klausa
<a name="r_WITH_clause"></a>

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

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

## Sintaksis
<a name="r_WITH_clause-synopsis"></a>

```
[ 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 *common\_table\_expression*:

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

## Parameter
<a name="r_WITH_clause-parameters"></a>

 REKURSIF   
Kata kunci yang mengidentifikasi kueri 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. 

 *common\_table\_expression*   
Mendefinisikan tabel sementara yang dapat Anda referensikan di [Klausa FROM](r_FROM_clause30.md) dan hanya digunakan selama eksekusi kueri yang dimilikinya. 

 *CTE\_TABLE\_NAME*   
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 di. [Klausa FROM](r_FROM_clause30.md)

 *column\_name*   
 Daftar nama kolom output untuk subquery klausa WITH, dipisahkan dengan 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* adalah opsional. Untuk CTE rekursif, daftar *column\_name* diperlukan.

 *query*   
 Kueri SELECT apa pun yang didukung Amazon Redshift. Lihat [SELECT](r_SELECT_synopsis.md). 

 *recursive\_query*   
Kueri UNION ALL yang terdiri dari dua subquery SELECT:  
+ *Subquery SELECT pertama tidak memiliki referensi rekursif ke CTE\_TABLE\_NAME yang sama.* Ia mengembalikan set hasil yang merupakan benih awal rekursi. Bagian ini disebut anggota awal atau anggota benih.
+ Subquery SELECT kedua mereferensikan *CTE\_TABLE\_NAME* yang sama dalam klausa FROM. Ini disebut anggota rekursif. *Recursive\_query* *berisi kondisi WHERE untuk mengakhiri recursive\_query.* 

## Catatan penggunaan
<a name="r_WITH_clause-usage-notes"></a>

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 subquery klausa WHERE. Anda tidak dapat mendefinisikan CTE rekursif di subquery. CTE rekursif harus mendahului klausa UPDATE.)
+ DELETE

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

Sebuah tabel yang didefinisikan oleh subquery klausa WITH dapat direferensikan hanya dalam lingkup kueri SELECT bahwa klausa WITH dimulai. Misalnya, Anda dapat mereferensikan tabel tersebut dalam klausa FROM dari subquery dalam daftar SELECT, klausa WHERE, atau HAVING. Anda tidak dapat menggunakan klausa WITH dalam subquery dan mereferensikan tabelnya di klausa FROM dari kueri utama atau subquery lainnya. Pola kueri ini menghasilkan pesan kesalahan 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 meneruskan referensi ke tabel yang ditentukan oleh subkueri klausa WITH. Misalnya, query berikut mengembalikan kesalahan karena referensi forward 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
<a name="r_WITH_clause-recursive-cte"></a>

*Ekspresi tabel umum rekursif (CTE) adalah CTE* yang mereferensikan dirinya sendiri. CTE rekursif berguna dalam kueri data hierarkis, seperti bagan organisasi yang menunjukkan hubungan pelaporan antara karyawan dan manajer. Lihat [Contoh: CTE rekursif](#r_WITH_clause-recursive-cte-example).

Penggunaan umum lainnya adalah tagihan 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 menyertakan klausa WHERE di subquery SELECT kedua dari kueri rekursif. Sebagai contoh, lihat [Contoh: CTE rekursif](#r_WITH_clause-recursive-cte-example). Jika tidak, kesalahan dapat terjadi serupa dengan yang berikut:
+ `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_rows`adalah parameter yang mengatur jumlah maksimum baris yang dapat dikembalikan oleh CTE rekursif untuk mencegah loop rekursi tak terbatas. Kami merekomendasikan untuk tidak mengubah ini ke nilai yang lebih besar daripada default. Ini mencegah masalah rekursi tak terbatas dalam kueri Anda mengambil ruang berlebihan di cluster Anda.

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

Anda tidak dapat menentukan klausa WITH RECURSIVE di dalam subquery. Anggota *recursive\_query* tidak dapat menyertakan klausa order by atau limit. 

## Contoh
<a name="r_WITH_clause-examples"></a>

Contoh berikut menunjukkan kasus yang paling sederhana dari query yang berisi klausa WITH. Query WITH bernama VENUECOPY memilih semua baris dari tabel VENUE. Kueri utama pada gilirannya memilih semua baris dari VENUECOPY. Tabel VENUECOPY hanya ada selama durasi 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 WITH query 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 kueri utama. Tabel yang ditentukan oleh klausa WITH (HOLIDAYS) direferensikan dalam klausa FROM subquery 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 mereferensikan tabel HOLIDAYS di kueri utama serta dalam subquery 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
<a name="r_WITH_clause-recursive-cte-example"></a>

Berikut ini adalah contoh CTE rekursif yang mengembalikan karyawan yang melapor secara langsung atau tidak langsung kepada John. Kueri rekursif berisi klausa WHERE untuk membatasi kedalaman rekursi hingga 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.](http://docs.aws.amazon.com/id_id/redshift/latest/dg/images/org-chart.png)
