Subquery mengembalikan tabel

Dan terakhir, opsi ketiga adalah saat subquery mengembalikan seluruh tabel. Ini adalah opsi yang paling umum.

Sangat sering ada situasi ketika kita ingin sedikit mengubah tabel tertentu. Dan baru kemudian bergabung (menggunakan operator JOIN ON) tabel yang dikoreksi dengan yang lain.

Mari kita mulai dengan kasus paling sederhana, di mana kita menggabungkan dua tabel dengan JOIN:

SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id

Dan seperti yang mungkin Anda ingat, ada tugas di tabel tugas yang tidak diberikan kepada siapa pun: employee_id adalah NULL .

Mari buat tabel yang dikoreksi , tempat kami menetapkan semua tugas gantung ke direktur (ID-nya = 4).

Untuk melakukan ini, kami menggunakan fungsi IFNULL() :

SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task 

Dan hasil dari kueri ini:

pengenal identitas pegawai nama tenggat waktu
1 1 Perbaiki bug di frontend 01-06-2022
2 2 Perbaiki bug di backend 15-06-2022
3 5 Beli kopi 01-07-2022
4 5 Beli kopi 01-08-2022
5 5 Beli kopi 01-09-2022
6 4 Membersihkan kantor (BATAL)
7 4 Menikmati hidup (BATAL)
8 6 Menikmati hidup (BATAL)

Sel yang diperbaiki ditandai dengan warna merah.

Sekarang mari kita gantikan tabel kita yang sudah dikoreksi ke dalam kueri:

SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id

Alih-alih tabel tugas .

Permintaan seperti itu akan terlihat seperti ini:

SELECT * FROM employee e JOIN ( 
 	SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline
 	FROM task 
) t ON e.id = t.emploee_id

Alih-alih kata task , kami menulis tanda kurung dan menempatkan isi permintaan di dalamnya.

Omong-omong, alias t (alias) untuk kueri bersarang sangat berguna. Kueri bersarang, tidak seperti tabel, tidak memiliki namanya sendiri, sehingga aliasnya sangat tidak pada tempatnya.

Dan inilah hasil dari kueri seperti itu:

pengenal nama pekerjaan gaji usia join_date pengenal identitas pegawai nama
1 Ivanov Ivan Programmer 100000 25 30-06-2012 1 1 Perbaiki bug di frontend
2 Petrov Petr Programmer 80000 23 12-08-2013 2 2 Perbaiki bug di backend
4 Rabinovich Moisha Direktur 200000 35 12-05-2015 6 4 Membersihkan kantor
4 Rabinovich Moisha Direktur 200000 35 12-05-2015 7 4 Menikmati hidup
5 Kirienko Anastasia Manajer kantor 40000 25 10-10-2015 4 5 Beli kopi
5 Kirienko Anastasia Manajer kantor 40000 25 10-10-2015 5 5 Beli kopi
5 Kirienko Anastasia Manajer kantor 40000 25 10-10-2015 3 5 Beli kopi
6 Vaska kucing 1000 3 11-11-2018 8 6 Menikmati hidup

Direktur kami memiliki tugas untuk "membersihkan kantor", saya pikir dia akan segera menemukan seseorang untuk didelegasikan :) Menggunakan pernyataan WITH

Omong-omong, dimulai dengan MySQL versi 8, Anda tidak lagi harus meletakkan semua subkueri tepat di dalam kueri terakhir. Mereka dapat dilakukan secara terpisah. Untuk ini, pernyataan WITH digunakan .

Ini memungkinkan Anda membuat tabel virtual (bernama kueri) dan tampilannya diberikan oleh templat:

WITH Name AS (request) 

Sering kali subkueri Anda memiliki kolom tanpa nama, seperti COUNT(*), yang belum Anda beri nama unik. Dalam hal ini, pernyataan WITH memiliki opsi untuk menentukan nama kolom baru untuk subquery.

Bentuk keduanya diberikan oleh templat:

WITH Name(column1, column2, …) AS (request) 

Anda dapat menggunakan tabel virtual (bernama kueri) sebanyak yang Anda inginkan dan merujuk satu sama lain di dalamnya. Bentuk umum permintaan Anda akan seperti ini:

WITH name1 AS (request1),  
       	name2 AS (request2), 
       	name3 AS (request3) 
SELECT * FROM name1 JOIN name2 ON

Sekarang mari ambil pertanyaan menakutkan kita:

SELECT * FROM employee e JOIN ( 
 	SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline 
 	FROM task 
) t ON e.id = t.emploee_id  

Dan tulis ulang menggunakan pernyataan WITH:

WITH task2(id, employee_id, name, deadline) 
   AS (SELECT id, IFNULL(employee_id, 4), name, deadline FROM task) 
SELECT * FROM employee e JOIN task2 t ON e.id = t.emploee_id

Atau Anda dapat melakukannya tanpa nama kolom, tetapi Anda harus menentukan alias untuk fungsi IFNULL() :

WITH task2 AS ( 
 	SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task 
) 
SELECT * FROM employee e JOIN task2 t ON e.id = t.emploee_id