Bagian 1 - Bergabung dan Serikat Pekerja
Jawaban ini mencakup:
- Bagian 1
- Bergabung dengan dua atau lebih tabel menggunakan gabungan dalam (Lihat entri wikipedia untuk info tambahan)
- Cara menggunakan kueri gabungan
- Gabungan Luar Kiri dan Kanan ( jawaban stackOverflow ini sangat bagus untuk menggambarkan tipe gabungan)
- Quers intersectect (dan bagaimana mereproduksi mereka jika database Anda tidak mendukung mereka) - ini adalah fungsi dari SQL-Server ( lihat info ) dan bagian dari alasan saya menulis semua ini di tempat pertama.
- Bagian 2
- Subqueries - apa itu, di mana mereka dapat digunakan dan apa yang harus diperhatikan
- Cartesian bergabung dengan AKA - Oh, kesengsaraan!
Ada sejumlah cara untuk mengambil data dari beberapa tabel dalam database. Dalam jawaban ini, saya akan menggunakan sintaks join ANSI-92. Ini mungkin berbeda dengan sejumlah tutorial lain di luar sana yang menggunakan sintaks ANSI-89 yang lebih lama (dan jika Anda terbiasa dengan 89, mungkin tampak jauh kurang intuitif - tetapi yang bisa saya katakan adalah mencobanya) karena jauh lebih mudah untuk memahami kapan pertanyaan mulai menjadi lebih kompleks. Kenapa menggunakannya? Apakah ada peningkatan kinerja? The Jawaban singkatnya adalah tidak, tetapi adalah lebih mudah dibaca setelah Anda terbiasa untuk itu. Lebih mudah membaca kueri yang ditulis oleh orang lain menggunakan sintaks ini.
Saya juga akan menggunakan konsep caryard kecil yang memiliki database untuk melacak mobil apa yang telah tersedia. Pemilik telah mempekerjakan Anda sebagai orang IT Computer-nya dan mengharapkan Anda untuk dapat memberikan data yang dia minta pada saat itu.
Saya telah membuat sejumlah tabel pencarian yang akan digunakan oleh tabel final. Ini akan memberi kita model yang masuk akal untuk bekerja. Untuk memulai, saya akan menjalankan kueri terhadap contoh database yang memiliki struktur berikut. Saya akan mencoba memikirkan kesalahan umum yang dibuat ketika memulai dan menjelaskan apa yang salah dengan mereka - dan tentu saja menunjukkan cara memperbaikinya.
Tabel pertama hanyalah daftar warna sehingga kita tahu warna apa yang kita miliki di halaman mobil.
mysql> create table colors(id int(3) not null auto_increment primary key,
-> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | varchar(15) | YES | | NULL | |
| paint | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> insert into colors (color, paint) values ('Red', 'Metallic'),
-> ('Green', 'Gloss'), ('Blue', 'Metallic'),
-> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from colors;
+----+-------+----------+
| id | color | paint |
+----+-------+----------+
| 1 | Red | Metallic |
| 2 | Green | Gloss |
| 3 | Blue | Metallic |
| 4 | White | Gloss |
| 5 | Black | Gloss |
+----+-------+----------+
5 rows in set (0.00 sec)
Tabel merek mengidentifikasi berbagai merek mobil yang bisa dijual caryard.
mysql> create table brands (id int(3) not null auto_increment primary key,
-> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| brand | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
mysql> insert into brands (brand) values ('Ford'), ('Toyota'),
-> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from brands;
+----+--------+
| id | brand |
+----+--------+
| 1 | Ford |
| 2 | Toyota |
| 3 | Nissan |
| 4 | Smart |
| 5 | BMW |
+----+--------+
5 rows in set (0.00 sec)
Tabel model akan mencakup berbagai jenis mobil, akan lebih mudah untuk menggunakan jenis mobil yang berbeda daripada model mobil yang sebenarnya.
mysql> create table models (id int(3) not null auto_increment primary key,
-> model varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| model | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from models;
+----+--------+
| id | model |
+----+--------+
| 1 | Sports |
| 2 | Sedan |
| 3 | 4WD |
| 4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)
Dan akhirnya, untuk mengikat semua tabel lainnya, tabel yang mengikat semuanya. Bidang ID sebenarnya nomor lot unik yang digunakan untuk mengidentifikasi mobil.
mysql> create table cars (id int(3) not null auto_increment primary key,
-> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | int(3) | YES | | NULL | |
| brand | int(3) | YES | | NULL | |
| model | int(3) | YES | | NULL | |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1),
-> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
| 1 | 1 | 2 | 1 |
| 2 | 3 | 1 | 2 |
| 3 | 5 | 3 | 1 |
| 4 | 4 | 4 | 2 |
| 5 | 2 | 2 | 3 |
| 6 | 3 | 5 | 4 |
| 7 | 4 | 1 | 3 |
| 8 | 2 | 2 | 1 |
| 9 | 5 | 2 | 3 |
| 10 | 4 | 5 | 1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)
Ini akan memberi kita cukup data (saya harap) untuk menutupi contoh-contoh di bawah ini dari berbagai jenis sambungan dan juga memberikan data yang cukup untuk menjadikannya berharga.
Jadi masuk ke grit itu, bos ingin tahu ID semua mobil sport yang dimilikinya .
Ini adalah gabungan dua tabel sederhana. Kami memiliki tabel yang mengidentifikasi model dan tabel dengan stok yang tersedia di dalamnya. Seperti yang Anda lihat, data di model
kolom cars
tabel terkait dengan models
kolom cars
tabel yang kita miliki. Sekarang, kita tahu bahwa tabel model memiliki ID 1
untuk Sports
jadi mari kita menulis join.
select
ID,
model
from
cars
join models
on model=ID
Jadi pertanyaan ini terlihat bagus bukan? Kami telah mengidentifikasi dua tabel dan berisi informasi yang kami butuhkan dan menggunakan gabungan yang mengidentifikasi kolom mana yang akan bergabung.
ERROR 1052 (23000): Column 'ID' in field list is ambiguous
Oh tidak! Kesalahan dalam kueri pertama kami! Ya, dan itu adalah buah prem. Soalnya, kueri memang punya kolom yang tepat, tetapi beberapa di antaranya ada di kedua tabel, sehingga database menjadi bingung tentang apa sebenarnya kolom yang kami maksud dan di mana. Ada dua solusi untuk mengatasi ini. Yang pertama bagus dan sederhana, bisa kita gunakan tableName.columnName
untuk memberi tahu database apa yang kita maksud, seperti ini:
select
cars.ID,
models.model
from
cars
join models
on cars.model=models.ID
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
| 2 | Sedan |
| 4 | Sedan |
| 5 | 4WD |
| 7 | 4WD |
| 9 | 4WD |
| 6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)
Yang lain mungkin lebih sering digunakan dan disebut table aliasing. Tabel dalam contoh ini memiliki nama sederhana yang bagus dan pendek, tetapi mengetikkan sesuatu seperti KPI_DAILY_SALES_BY_DEPARTMENT
mungkin akan menjadi cepat, jadi cara sederhana adalah dengan memberi nama tabel pada tabel seperti ini:
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
Sekarang, kembali ke permintaan. Seperti yang Anda lihat, kami memiliki informasi yang kami butuhkan, tetapi kami juga memiliki informasi yang tidak diminta, jadi kami harus menyertakan klausa di mana dalam pernyataan untuk hanya mendapatkan mobil Sport seperti yang diminta. Karena saya lebih suka metode tabel alias daripada menggunakan nama tabel berulang kali, saya akan tetap menggunakannya sejak saat ini dan seterusnya.
Jelas, kita perlu menambahkan klausa tempat ke kueri kami. Kami dapat mengidentifikasi mobil Sport baik dengan ID=1
atau model='Sports'
. Karena ID diindeks dan kunci utama (dan itu terjadi kurang mengetik), mari kita gunakan dalam kueri kami.
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
Bingo! Bos senang. Tentu saja, sebagai bos dan tidak pernah senang dengan apa yang dia minta, dia melihat informasinya, lalu berkata aku ingin warnanya juga .
Oke, jadi kita sudah memiliki bagian yang baik dari permintaan kita yang sudah ditulis, tetapi kita perlu menggunakan tabel ketiga yang berwarna. Sekarang, tabel informasi utama kami cars
menyimpan ID warna mobil dan tautan ini kembali ke kolom ID warna. Jadi, dengan cara yang mirip dengan aslinya, kita bisa bergabung dengan tabel ketiga:
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
Sial, meskipun tabel bergabung dengan benar dan kolom terkait telah ditautkan, kami lupa untuk menarik informasi aktual dari tabel baru yang baru saja kami tautkan.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
+----+--------+-------+
4 rows in set (0.00 sec)
Benar, itu bos di belakang kita sejenak. Sekarang, untuk menjelaskan beberapa hal ini dengan sedikit lebih detail. Seperti yang Anda lihat, from
klausa dalam pernyataan kami menautkan tabel utama kami (saya sering menggunakan tabel yang berisi informasi daripada tabel pencarian atau dimensi. Kueri akan bekerja sama baiknya dengan semua tabel yang diputar, tetapi kurang masuk akal saat kami kembali ke kueri ini untuk membacanya dalam waktu beberapa bulan, jadi sering kali paling baik untuk mencoba menulis kueri yang bagus dan mudah dipahami - lay out secara intuitif, gunakan indentasi yang bagus sehingga semuanya sejelas seperti Jika Anda terus mengajar orang lain, cobalah untuk menanamkan karakteristik ini dalam permintaan mereka - terutama jika Anda akan memecahkan masalah mereka.
Sangat mungkin untuk terus menautkan semakin banyak tabel dengan cara ini.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
Meskipun saya lupa menyertakan tabel di mana kami mungkin ingin bergabung lebih dari satu kolom dalam join
pernyataan, berikut adalah contohnya. Jika models
tabel memiliki model khusus merek dan oleh karena itu juga memiliki kolom yang disebut brand
yang terhubung kembali ke brands
tabel di ID
lapangan, bisa dilakukan sebagai berikut:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
and b.brand=d.ID
where
b.ID=1
Anda dapat melihat, kueri di atas tidak hanya menautkan tabel yang bergabung ke tabel utama cars
, tetapi juga menentukan gabungan antara tabel yang sudah bergabung. Jika ini tidak dilakukan, hasilnya disebut bergabung kartesian - yang dba berbicara buruk. Penggabungan kartesian adalah tempat baris dikembalikan karena informasi tidak memberi tahu database cara membatasi hasil, sehingga kueri mengembalikan semua baris yang sesuai dengan kriteria.
Jadi, untuk memberikan contoh gabungan kartesian, mari jalankan query berikut:
select
a.ID,
b.model
from
cars a
join models b
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 1 | Sedan |
| 1 | 4WD |
| 1 | Luxury |
| 2 | Sports |
| 2 | Sedan |
| 2 | 4WD |
| 2 | Luxury |
| 3 | Sports |
| 3 | Sedan |
| 3 | 4WD |
| 3 | Luxury |
| 4 | Sports |
| 4 | Sedan |
| 4 | 4WD |
| 4 | Luxury |
| 5 | Sports |
| 5 | Sedan |
| 5 | 4WD |
| 5 | Luxury |
| 6 | Sports |
| 6 | Sedan |
| 6 | 4WD |
| 6 | Luxury |
| 7 | Sports |
| 7 | Sedan |
| 7 | 4WD |
| 7 | Luxury |
| 8 | Sports |
| 8 | Sedan |
| 8 | 4WD |
| 8 | Luxury |
| 9 | Sports |
| 9 | Sedan |
| 9 | 4WD |
| 9 | Luxury |
| 10 | Sports |
| 10 | Sedan |
| 10 | 4WD |
| 10 | Luxury |
+----+--------+
40 rows in set (0.00 sec)
Ya Tuhan, itu jelek. Namun, sejauh menyangkut database, itu persis apa yang diminta. Dalam kueri, kami meminta ID
dari cars
dan model
dari models
. Namun, karena kami tidak menentukan cara bergabung dengan tabel, database telah mencocokkan setiap baris dari tabel pertama dengan setiap baris dari tabel kedua.
Oke, jadi bos sudah kembali, dan dia ingin lebih banyak informasi lagi. Saya ingin daftar yang sama, tetapi juga menyertakan 4WD di dalamnya .
Namun ini, memberi kita alasan besar untuk melihat dua cara berbeda untuk mencapai ini. Kita dapat menambahkan kondisi lain ke klausa di mana seperti ini:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
or b.ID=3
Meskipun hal di atas akan bekerja dengan baik, mari kita lihat secara berbeda, ini adalah alasan yang bagus untuk menunjukkan bagaimana sebuah union
kueri akan bekerja.
Kita tahu bahwa yang berikut akan mengembalikan semua mobil Sport:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
Dan yang berikut ini akan mengembalikan semua 4WD:
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
Jadi dengan menambahkan union all
klausa di antara mereka, hasil permintaan kedua akan ditambahkan ke hasil permintaan pertama.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
union all
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
| 5 | 4WD | Green |
| 7 | 4WD | White |
| 9 | 4WD | Black |
+----+--------+-------+
7 rows in set (0.00 sec)
Seperti yang Anda lihat, hasil dari query pertama dikembalikan terlebih dahulu, diikuti oleh hasil dari query kedua.
Dalam contoh ini, tentu saja akan jauh lebih mudah untuk hanya menggunakan kueri pertama, tetapi union
kueri bisa bagus untuk kasus-kasus tertentu. Mereka adalah cara yang bagus untuk mengembalikan hasil spesifik dari tabel dari tabel yang tidak mudah bergabung bersama - atau dalam hal ini tabel yang sama sekali tidak terkait. Namun ada beberapa aturan yang harus diikuti.
- Jenis kolom dari kueri pertama harus cocok dengan jenis kolom dari setiap kueri lainnya di bawah ini.
- Nama-nama kolom dari kueri pertama akan digunakan untuk mengidentifikasi seluruh rangkaian hasil.
- Jumlah kolom di setiap kueri harus sama.
Sekarang, Anda mungkin bertanya-tanya apa perbedaan antara menggunakan union
dan union all
. Sebuah union
permintaan akan menghapus duplikat, sementara union all
tidak akan. Ini berarti bahwa ada hit kinerja kecil ketika menggunakan union
lebih dari union all
tetapi hasilnya mungkin sepadan - saya tidak akan berspekulasi pada hal semacam itu dalam hal ini sekalipun.
Pada catatan ini, mungkin perlu dicatat beberapa catatan tambahan di sini.
- Jika kami ingin memesan hasilnya, kami dapat menggunakan
order by
tetapi Anda tidak dapat menggunakan alias lagi. Dalam kueri di atas, menambahkan suatu order by a.ID
akan menghasilkan kesalahan - sejauh menyangkut hasil, kolom disebut ID
bukan a.ID
- meskipun alias yang sama telah digunakan di kedua kueri.
- Kami hanya dapat memiliki satu
order by
pernyataan, dan itu harus sebagai pernyataan terakhir.
Untuk contoh berikutnya, saya menambahkan beberapa baris tambahan ke tabel kami.
Saya telah menambahkan Holden
ke tabel merek. Saya juga menambahkan baris ke dalam cars
yang memiliki color
nilai 12
- yang tidak memiliki referensi dalam tabel warna.
Oke, bos kembali lagi, menggonggong permintaan - * Saya ingin hitungan masing-masing merek yang kami bawa dan jumlah mobil di dalamnya! .
Rightyo, jadi hal pertama yang perlu kita lakukan adalah mendapatkan daftar lengkap merek yang mungkin.
select
a.brand
from
brands a
+--------+
| brand |
+--------+
| Ford |
| Toyota |
| Nissan |
| Smart |
| BMW |
| Holden |
+--------+
6 rows in set (0.00 sec)
Sekarang, ketika kita bergabung ini ke meja mobil kita, kita mendapatkan hasil berikut:
select
a.brand
from
brands a
join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Nissan |
| Smart |
| Toyota |
+--------+
5 rows in set (0.00 sec)
Yang tentu saja merupakan masalah - kami tidak melihat penyebutan Holden
merek indah yang saya tambahkan.
Ini karena gabungan mencari baris yang cocok di kedua tabel. Karena tidak ada data di mobil yang bertipe Holden
tidak dikembalikan. Di sinilah kita bisa menggunakan outer
gabungan. Ini akan mengembalikan semua hasil dari satu tabel apakah mereka cocok di tabel lain atau tidak:
select
a.brand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Holden |
| Nissan |
| Smart |
| Toyota |
+--------+
6 rows in set (0.00 sec)
Sekarang kita memiliki itu, kita dapat menambahkan fungsi agregat yang indah untuk mendapatkan hitungan dan membuat bos mundur sejenak.
select
a.brand,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+--------------+
| brand | countOfBrand |
+--------+--------------+
| BMW | 2 |
| Ford | 2 |
| Holden | 0 |
| Nissan | 1 |
| Smart | 1 |
| Toyota | 5 |
+--------+--------------+
6 rows in set (0.00 sec)
Dan dengan itu, singkirkan bos yang susah.
Sekarang, untuk menjelaskan ini secara lebih rinci, sambungan luar bisa dari tipe left
atau right
. Kiri atau Kanan menentukan tabel mana yang sepenuhnya disertakan. A left outer join
akan memasukkan semua baris dari tabel di sebelah kiri, sementara (Anda dapat menebaknya) a right outer join
membawa semua hasil dari tabel di sebelah kanan ke dalam hasil.
Beberapa database akan memungkinkan full outer join
yang akan mengembalikan hasil (apakah cocok atau tidak) dari kedua tabel, tetapi ini tidak didukung di semua database.
Sekarang, saya mungkin memikirkan saat ini, Anda bertanya-tanya apakah Anda dapat menggabungkan jenis bergabung dalam kueri - dan jawabannya adalah ya, Anda benar-benar bisa.
select
b.brand,
c.color,
count(a.id) as countOfBrand
from
cars a
right outer join brands b
on b.ID=a.brand
join colors c
on a.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| Ford | Blue | 1 |
| Ford | White | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| BMW | Blue | 1 |
| BMW | White | 1 |
+--------+-------+--------------+
9 rows in set (0.00 sec)
Jadi, mengapa itu bukan hasil yang diharapkan? Itu karena meskipun kami telah memilih gabung luar dari mobil ke merek, itu tidak ditentukan dalam gabung ke warna - sehingga gabung tertentu hanya akan membawa kembali hasil yang cocok di kedua tabel.
Berikut adalah kueri yang akan berfungsi untuk mendapatkan hasil yang kami harapkan:
select
a.brand,
c.color,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
left outer join colors c
on b.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| BMW | Blue | 1 |
| BMW | White | 1 |
| Ford | Blue | 1 |
| Ford | White | 1 |
| Holden | NULL | 0 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| Toyota | NULL | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
+--------+-------+--------------+
11 rows in set (0.00 sec)
Seperti yang dapat kita lihat, kita memiliki dua gabungan luar dalam kueri dan hasilnya akan seperti yang diharapkan.
Sekarang, bagaimana dengan jenis-jenis sambungan yang Anda tanyakan? Bagaimana dengan titik-temu?
Yah, tidak semua database mendukung, intersection
tetapi hampir semua database akan memungkinkan Anda untuk membuat persimpangan melalui gabungan (atau pernyataan yang terstruktur dengan baik setidaknya).
Persimpangan adalah jenis gabungan yang agak mirip dengan yang union
dijelaskan di atas - tetapi perbedaannya adalah bahwa ia hanya mengembalikan baris data yang identik (dan maksud saya identik) antara berbagai kueri individual yang digabungkan oleh serikat. Hanya baris yang identik dalam setiap hal yang akan dikembalikan.
Contoh sederhana akan seperti itu:
select
*
from
colors
where
ID>2
intersect
select
*
from
colors
where
id<4
Sementara union
kueri normal akan mengembalikan semua baris tabel (kueri pertama mengembalikan apa pun ID>2
dan yang kedua memiliki ID<4
), yang akan menghasilkan set lengkap, kueri intersect hanya akan mengembalikan pencocokan baris id=3
karena memenuhi kedua kriteria.
Sekarang, jika basis data Anda tidak mendukung intersect
kueri, hal di atas dapat dengan mudah dilakukan dengan kueri berikut:
select
a.ID,
a.color,
a.paint
from
colors a
join colors b
on a.ID=b.ID
where
a.ID>2
and b.ID<4
+----+-------+----------+
| ID | color | paint |
+----+-------+----------+
| 3 | Blue | Metallic |
+----+-------+----------+
1 row in set (0.00 sec)
Jika Anda ingin melakukan persimpangan di dua tabel yang berbeda menggunakan database yang secara inheren tidak mendukung kueri persimpangan, Anda perlu membuat gabungan di setiap kolom tabel.