Pengantar
Memisahkan data terkait ke dalam tabel terpisah dapat bermanfaat dari sudut pandang konsistensi, fleksibilitas, dan jenis kinerja tertentu. Namun, Anda masih memerlukan cara yang wajar untuk mengintegrasikan kembali catatan saat informasi yang relevan mencakup beberapa tabel.
Dalam database relasional, bergabung menawarkan cara untuk menggabungkan catatan dalam dua atau lebih tabel berdasarkan nilai bidang umum. Jenis gabungan yang berbeda dapat mencapai hasil yang berbeda tergantung pada bagaimana baris yang tidak cocok harus ditangani. Dalam panduan ini, kita akan membahas berbagai jenis gabungan yang ditawarkan PostgreSQL dan bagaimana Anda dapat menggunakannya untuk menggabungkan data tabel dari berbagai sumber.
Apa itu join?
Singkatnya, bergabung adalah cara menampilkan data dari beberapa tabel. Mereka melakukan ini dengan menggabungkan catatan dari sumber yang berbeda berdasarkan nilai yang cocok di kolom tertentu. Setiap baris yang dihasilkan terdiri dari record dari tabel pertama yang digabungkan dengan baris dari tabel kedua, berdasarkan satu atau beberapa kolom di setiap tabel yang memiliki nilai yang sama.
Sintaks dasar gabungan terlihat seperti ini:
SELECT *FROM <first_table><join_type> <second_table> <join_condition>;
Dalam gabungan, setiap baris yang dihasilkan dibangun dengan memasukkan semua kolom dari tabel pertama diikuti oleh semua kolom dari tabel kedua. SELECT
bagian dari kueri dapat digunakan untuk menentukan kolom persis yang ingin Anda tampilkan.
Beberapa baris dapat dibuat dari tabel asli jika nilai dalam kolom yang digunakan untuk perbandingan tidak unik. Misalnya, bayangkan Anda memiliki kolom yang dibandingkan dari tabel pertama yang memiliki dua catatan dengan nilai "merah". Yang cocok dengan ini adalah kolom dari tabel kedua yang memiliki tiga baris dengan nilai itu. Gabung akan menghasilkan enam baris berbeda untuk nilai yang mewakili berbagai kombinasi yang dapat dicapai.
Jenis gabungan dan kondisi gabungan menentukan bagaimana setiap baris yang ditampilkan dibuat. Ini memengaruhi apa yang terjadi pada baris dari setiap tabel yang melakukan dan melakukan tidak memiliki kecocokan dengan syarat bergabung.
Demi kenyamanan, banyak gabungan yang cocok dengan kunci utama pada satu tabel dengan kunci asing terkait di tabel kedua. Meskipun kunci utama dan kunci asing hanya digunakan oleh sistem database untuk menjaga jaminan konsistensi, hubungan mereka sering kali menjadikannya kandidat yang baik untuk kondisi bergabung.
Berbagai jenis gabungan
Berbagai jenis gabungan tersedia, yang masing-masing berpotensi menghasilkan hasil yang berbeda. Memahami bagaimana setiap jenis dibangun akan membantu Anda menentukan mana yang sesuai untuk skenario yang berbeda.
Gabungan dalam
Gabung default disebut gabung dalam . Di PostgreSQL, ini dapat ditentukan menggunakan INNER JOIN
atau cukup JOIN
.
Berikut adalah contoh tipikal yang menunjukkan sintaks gabungan dalam:
SELECT *FROM table_1[INNER] JOIN table_2 ON table_1.id = table_2.table_1_id;
Inner join adalah tipe join yang paling membatasi karena hanya menampilkan baris yang dibuat dengan menggabungkan baris dari setiap tabel. Setiap baris dalam tabel konstituen yang tidak memiliki pasangan yang cocok di tabel lain akan dihapus dari hasil. Misalnya, jika tabel pertama memiliki nilai "biru" di kolom perbandingan, dan tabel kedua tidak memiliki catatan dengan nilai tersebut, baris tersebut akan dihapus dari output.
Jika Anda mewakili hasil sebagai diagram Venn dari tabel komponen, gabungan bagian dalam memungkinkan Anda untuk mewakili area yang tumpang tindih dari dua lingkaran. Tidak ada nilai yang hanya ada di salah satu tabel yang ditampilkan.
Gabung kiri
Gabung kiri adalah gabungan yang menunjukkan semua record yang ditemukan di gabungan dalam, ditambah semua yang tidak cocok baris dari tabel pertama. Di PostgreSQL, ini dapat ditentukan sebagai LEFT OUTER JOIN
atau hanya sebagai LEFT JOIN
.
Sintaks dasar dari gabungan kiri mengikuti pola ini:
SELECT *FROM table_1LEFT JOIN table_2 ON table_1.id = table_2.table_1_id;
Gabung kiri dibangun dengan terlebih dahulu melakukan gabungan dalam untuk membangun baris dari semua catatan yang cocok di kedua tabel. Setelah itu, catatan tak tertandingi dari tabel pertama juga disertakan. Karena setiap baris dalam gabungan menyertakan kolom dari kedua tabel, kolom yang tidak cocok menggunakan NULL
sebagai nilai untuk semua kolom di tabel kedua.
Jika Anda mewakili hasilnya sebagai diagram Venn dari tabel komponen, gabungan kiri memungkinkan Anda untuk mewakili seluruh lingkaran kiri. Bagian lingkaran kiri yang diwakili oleh perpotongan antara dua lingkaran akan memiliki data tambahan yang dilengkapi dengan tabel kanan.
Gabung kanan
Gabung kanan adalah Gabungan yang menunjukkan semua record yang ditemukan di Gabungan dalam, ditambah semua yang tidak cocok baris dari tabel kedua. Di PostgreSQL, ini dapat ditentukan sebagai RIGHT OUTER JOIN
atau hanya sebagai RIGHT JOIN
.
Sintaks dasar dari gabungan kanan mengikuti pola ini:
SELECT *FROM table_1RIGHT JOIN table_2 ON table_1.id = table_2.table_1_id;
Gabung kanan dibangun dengan terlebih dahulu melakukan gabungan dalam untuk membuat baris dari semua catatan yang cocok di kedua tabel. Setelah itu, catatan yang tak tertandingi dari tabel kedua juga disertakan. Karena setiap baris dalam gabungan menyertakan kolom dari kedua tabel, kolom yang tidak cocok menggunakan NULL
sebagai nilai untuk semua kolom di tabel pertama.
Jika Anda mewakili hasilnya sebagai diagram Venn dari tabel komponen, gabungan kanan memungkinkan Anda untuk mewakili seluruh lingkaran kanan. Bagian lingkaran kanan yang diwakili oleh perpotongan antara dua lingkaran akan memiliki data tambahan yang dilengkapi dengan tabel kiri.
Gabung penuh
Gabung penuh adalah gabungan yang menunjukkan semua record yang ditemukan di dalam gabungan, ditambah semua yang tidak cocok baris dari kedua tabel komponen. Di PostgreSQL, ini dapat ditentukan sebagai FULL OUTER JOIN
atau hanya sebagai FULL JOIN
.
Sintaks dasar dari full join mengikuti pola ini:
SELECT *FROM table_1FULL JOIN table_2 ON table_1.id = table_2.table_1_id;
Gabung penuh dibangun dengan terlebih dahulu melakukan gabungan dalam untuk membangun baris dari semua catatan yang cocok di kedua tabel. Setelah itu, catatan yang tidak cocok dari kedua tabel juga disertakan. Karena setiap baris dalam gabungan menyertakan kolom dari kedua tabel, kolom yang tidak cocok menggunakan NULL
sebagai nilai untuk semua kolom di tabel lain yang tak tertandingi.
Jika Anda mewakili hasil sebagai diagram Venn dari tabel komponen, gabungan penuh memungkinkan Anda untuk mewakili kedua lingkaran komponen seluruhnya. Perpotongan dua lingkaran akan memiliki nilai yang disediakan oleh masing-masing tabel komponen. Bagian lingkaran di luar area yang tumpang tindih akan memiliki nilai dari tabel tempatnya berada, menggunakan NULL
untuk mengisi kolom yang terdapat pada tabel lainnya.
Gabungan silang
Gabung khusus yang disebut CROSS JOIN
juga tersedia. Gabungan silang tidak menggunakan perbandingan apa pun untuk menentukan apakah baris di setiap tabel cocok satu sama lain. Sebagai gantinya, hasil dibuat hanya dengan menambahkan setiap baris dari tabel pertama ke setiap baris dari tabel kedua.
Ini menghasilkan produk Cartesian dari baris dalam dua atau lebih tabel. Akibatnya, gaya gabungan ini menggabungkan baris dari setiap tabel tanpa syarat. Jadi, jika setiap tabel memiliki tiga baris, tabel yang dihasilkan akan memiliki sembilan baris yang berisi semua kolom dari kedua tabel.
Misalnya, jika Anda memiliki tabel bernama t1
digabungkan dengan tabel yang disebut t2
, masing-masing dengan baris r1
, r2
, dan r3
, hasilnya akan menjadi sembilan baris yang digabungkan seperti ini:
t1.r1 + t2.r1t1.r1 + t2.r2t1.r1 + t2.r3t1.r2 + t2.r1t1.r2 + t2.r2t1.r2 + t2.r3t1.r3 + t2.r1t1.r3 + t2.r2t1.r3 + t2.r3
Self-join
Gabungan sendiri adalah gabungan apa pun yang menggabungkan baris-baris tabel dengan dirinya sendiri. Mungkin tidak langsung terlihat bagaimana ini bisa berguna, tetapi sebenarnya memiliki banyak aplikasi umum.
Seringkali, tabel menggambarkan entitas yang dapat memenuhi beberapa peran dalam hubungan satu sama lain. Misalnya, jika Anda memiliki tabel people
, setiap baris berpotensi berisi mother
kolom yang mereferensikan people
lainnya di meja. Penggabungan sendiri akan memungkinkan Anda untuk menggabungkan baris yang berbeda ini dengan menggabungkan contoh kedua dari tabel ke yang pertama di mana nilai-nilai ini cocok.
Karena self join mereferensikan tabel yang sama dua kali, alias tabel diperlukan untuk memperjelas referensi. Pada contoh di atas, misalnya, Anda dapat menggabungkan dua instance people
tabel menggunakan alias people AS children
dan people AS mothers
. Dengan begitu, Anda dapat menentukan instance tabel mana yang Anda rujuk saat menentukan kondisi gabungan.
Berikut adalah contoh lain, kali ini mewakili hubungan antara karyawan dan manajer:
SELECT *FROM people AS employeeJOIN people AS manager ON employee.manager_id = manager.id;
Kondisi bergabung
Saat menggabungkan tabel, kondisi gabungan menentukan bagaimana baris akan dicocokkan bersama untuk membentuk hasil gabungan. Premis dasarnya adalah untuk menentukan kolom di setiap tabel yang harus cocok agar gabungan terjadi pada baris itu.
The ON
klausa
Cara paling standar untuk mendefinisikan kondisi penggabungan tabel adalah dengan ON
ayat. Tombol ON
klausa menggunakan tanda sama dengan untuk menentukan kolom yang tepat dari setiap tabel yang akan dibandingkan untuk menentukan kapan bergabung dapat terjadi. PostgreSQL menggunakan kolom yang disediakan untuk menyatukan baris dari setiap tabel.
Tombol ON
klausa adalah yang paling verbose, tetapi juga yang paling fleksibel dari kondisi bergabung yang tersedia. Ini memungkinkan kekhususan terlepas dari seberapa standar nama kolom dari setiap tabel yang digabungkan.
Sintaks dasar ON
klausanya seperti ini:
SELECT *FROM table1JOIN table2ON table1.id = table2.ident;
Di sini, baris dari table1
dan table2
akan bergabung setiap kali id
kolom dari table1
cocok dengan ident
kolom dari table2
. Karena inner join digunakan, hasilnya hanya akan menampilkan baris yang digabungkan. Karena kueri menggunakan karakter pengganti *
karakter, semua kolom dari kedua tabel akan ditampilkan.
Ini berarti bahwa kedua id
kolom dari table1
dan ident
kolom dari table2
akan ditampilkan, meskipun mereka memiliki nilai yang sama persis berdasarkan memenuhi kondisi bergabung. Anda dapat menghindari duplikasi ini dengan memanggil kolom persis yang ingin Anda tampilkan di SELECT
daftar kolom.
The USING
klausa
USING
klausa adalah singkatan untuk menentukan kondisi ON
klausa yang dapat digunakan ketika kolom yang dibandingkan memiliki nama yang sama di kedua tabel. USING
klausa mengambil daftar, terlampir dalam tanda kurung, dari nama kolom bersama yang harus dibandingkan.
Sintaks umum USING
klausa menggunakan format ini:
SELECT *FROM table1JOIN table2USING (id, state);
Gabung ini menggabungkan table1
dengan table2
ketika dua kolom yang digunakan bersama oleh kedua tabel (id
dan state
) masing-masing memiliki nilai yang cocok.
Gabungan yang sama ini dapat diekspresikan secara lebih verbose dengan menggunakan ON
seperti ini:
SELECT *FROM table1JOIN table2ON table1.id = table2.id AND table1.state = table2.state;
Sementara kedua gabungan di atas akan menghasilkan baris yang sama yang dibangun dengan data yang sama, mereka akan ditampilkan sedikit berbeda. Sedangkan tombol ON
klausa mencakup semua kolom dari kedua tabel, USING
klausa menekan kolom duplikat. Jadi, alih-alih ada dua id
yang terpisah kolom dan dua state
separate yang terpisah kolom (satu untuk setiap tabel), hasilnya hanya akan memiliki satu dari masing-masing kolom bersama, diikuti oleh semua kolom lain yang disediakan oleh table1
dan table2
.
The NATURAL
klausa
NATURAL
klausa adalah singkatan lain yang selanjutnya dapat mengurangi verbositas USING
ayat. Sebuah NATURAL
bergabung tidak menentukan apa pun kolom yang akan dicocokkan. Sebagai gantinya, PostgreSQL akan secara otomatis menggabungkan tabel berdasarkan semua kolom yang memiliki kolom yang cocok di setiap database.
Sintaks umum NATURAL
klausa join terlihat seperti ini:
SELECT *FROM table1NATURAL JOIN table2;
Dengan asumsi bahwa table1
dan table2
keduanya memiliki kolom bernama id
, state
, dan company
, kueri di atas akan setara dengan kueri ini menggunakan ON
klausa:
SELECT *FROM table1JOIN table2ON table1.id = table2.id AND table1.state = table2.state AND table1.company = table2.company;
Dan query ini menggunakan USING
klausa:
SELECT *FROM table1JOIN table2USING (id, state, company);
Seperti USING
klausa, NATURAL
klausa menekan kolom duplikat, jadi hanya akan ada satu contoh dari masing-masing kolom yang digabungkan dalam hasil.
Sedangkan NATURAL
klausa dapat mengurangi verbositas pertanyaan Anda, kehati-hatian harus dilakukan saat menggunakannya. Karena kolom yang digunakan untuk menggabungkan tabel dihitung secara otomatis, jika kolom dalam tabel komponen berubah, hasilnya bisa sangat berbeda karena kondisi penggabungan yang baru.
Kondisi bergabung dan WHERE
klausa
Kondisi gabungan berbagi banyak karakteristik dengan perbandingan yang digunakan untuk memfilter baris data menggunakan WHERE
klausa. Kedua konstruksi mendefinisikan ekspresi yang harus dievaluasi menjadi benar untuk baris yang akan dipertimbangkan. Karena itu, tidak selalu intuitif apa perbedaan antara memasukkan perbandingan tambahan dalam WHERE
membangun versus mendefinisikannya di dalam klausa gabungan itu sendiri.
Untuk memahami perbedaan yang akan dihasilkan, kita harus melihat urutan di mana PostgreSQL memproses bagian kueri yang berbeda. Dalam hal ini, predikat dalam kondisi join diproses terlebih dahulu untuk membuat tabel virtual join di memori. Setelah tahap ini, ekspresi dalam WHERE
klausa dievaluasi untuk menyaring baris yang dihasilkan.
Sebagai contoh, misalkan kita memiliki dua tabel bernama customer
dan order
bahwa kita harus bersatu. Kami ingin menggabungkan dua tabel dengan mencocokkan customer.id
kolom dengan order.customer_id
kolom. Selain itu, kami tertarik pada baris dalam order
tabel yang memiliki product_id
dari 12345.
Mengingat persyaratan di atas, kami memiliki dua kondisi yang kami pedulikan. Namun, cara kami mengungkapkan kondisi ini akan menentukan hasil yang kami terima.
Pertama, mari kita gunakan keduanya sebagai kondisi gabungan untuk LEFT JOIN
:
SELECT customer.id AS customer_id, customer.name, order.id AS order_id, order.product_idFROM customerLEFT JOIN orderON customer.id = order.customer_id AND order.product_id = 12345;
Hasilnya berpotensi terlihat seperti ini:
customer_id | name | order_id | product_id ------------+----------+----------+------------ 4380 | Acme Co | 480 | 12345 4380 | Acme Co | 182 | 12345 320 | Other Co | 680 | 12345 4380 | Acme Co | | 320 | Other Co | | 20 | Early Co | | 8033 | Big Co | |(7 rows)
PostgreSQL sampai pada hasil ini dengan melakukan operasi berikut:
- Gabungkan baris apa pun di
customer
tabel denganorder
tabel di mana:customer.id
cocok denganorder.customer_id
.order.product_id
cocok dengan 12345
- Karena kami menggunakan gabungan kiri, sertakan yang tidak cocok baris dari tabel kiri (
customer
), mengisi kolom dari tabel kanan (order
) denganNULL
nilai. - Hanya tampilkan kolom yang tercantum dalam
SELECT
spesifikasi kolom.
Hasilnya adalah semua baris yang kami gabungkan cocok dengan kedua kondisi yang kami cari. Namun, gabungan kiri menyebabkan PostgreSQL juga menyertakan setiap baris dari tabel pertama yang tidak memenuhi kondisi gabungan. Ini menghasilkan baris "tersisa" yang tampaknya tidak mengikuti maksud kueri yang tampak.
Jika kita memindahkan kueri kedua (order.product_id
=12345) ke WHERE
klausa, alih-alih memasukkannya sebagai kondisi gabungan, kami mendapatkan hasil yang berbeda:
SELECT customer.id AS customer_id, customer.name, order.id AS order_id, order.product_idFROM customerLEFT JOIN orderON customer.id = order.customer_idWHERE order.product_id = 12345;
Kali ini, hanya tiga baris yang ditampilkan:
customer_id | name | order_id | product_id ------------+----------+----------+------------ 4380 | Acme Co | 480 | 12345 4380 | Acme Co | 182 | 12345 320 | Other Co | 680 | 12345(3 rows)
Urutan di mana perbandingan dijalankan adalah alasan untuk perbedaan ini. Kali ini, PostgreSQL memproses kueri seperti ini:
- Gabungkan baris apa pun di
customer
tabel denganorder
tabel di manacustomer.id
cocok denganorder.customer_id
. - Karena kami menggunakan gabungan kiri, sertakan yang tidak cocok baris dari tabel kiri (
customer
), mengisi kolom dari tabel kanan (order
) denganNULL
nilai. - Evaluasi
WHERE
klausa untuk menghapus baris yang tidak memiliki 12345 sebagai nilai untukorder.product_id
kolom. - Hanya tampilkan kolom yang tercantum dalam
SELECT
spesifikasi kolom.
Kali ini, meskipun kita menggunakan gabungan kiri, WHERE
klausa memotong hasil dengan memfilter semua baris tanpa product_id
yang benar . Karena setiap baris yang tidak cocok akan memiliki product_id
setel ke NULL
, ini menghapus semua baris yang tidak cocok yang diisi oleh gabungan kiri. Ini juga menghapus baris mana pun yang cocok dengan kondisi gabungan yang tidak lolos pemeriksaan putaran kedua ini.
Memahami proses dasar yang digunakan PostgreSQL untuk mengeksekusi kueri Anda dapat membantu Anda menghindari beberapa kesalahan yang mudah dibuat tetapi sulit di-debug saat Anda bekerja dengan data Anda.
Kesimpulan
Dalam panduan ini, kami membahas bagaimana gabungan mengaktifkan database relasional untuk menggabungkan data dari tabel yang berbeda untuk memberikan jawaban yang lebih berharga. Kami berbicara tentang berbagai gabungan yang didukung PostgreSQL, cara setiap jenis mengumpulkan hasilnya, dan apa yang diharapkan saat menggunakan jenis gabungan tertentu. Setelah itu, kami membahas berbagai cara untuk menentukan kondisi gabungan dan melihat bagaimana interaksi antara gabungan dan WHERE
klausa dapat menyebabkan kejutan.
Bergabung adalah bagian penting dari apa yang membuat database relasional cukup kuat dan fleksibel untuk menangani begitu banyak jenis kueri yang berbeda. Mengorganisir data menggunakan batasan logis sambil tetap dapat menggabungkan kembali data dengan cara baru berdasarkan kasus per kasus memberikan database relasional seperti PostgreSQL keserbagunaan yang luar biasa. Mempelajari cara melakukan penggabungan antar tabel ini akan memungkinkan Anda membuat kueri yang lebih kompleks dan mengandalkan database untuk membuat gambar lengkap data Anda.