Subquery mengembalikan jadual

Dan akhirnya, pilihan ketiga ialah apabila subquery mengembalikan keseluruhan jadual. Ini adalah pilihan yang paling biasa.

Selalunya terdapat situasi apabila kita ingin mengubah sedikit jadual tertentu. Dan hanya kemudian sertai (menggunakan operator JOIN ON) jadual yang dibetulkan dengan yang lain.

Mari kita mulakan dengan kes yang paling mudah, di mana kita menyertai dua jadual dengan JOIN:

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

Dan seperti yang anda mungkin ingat, terdapat tugas dalam jadual tugas yang tidak diberikan kepada sesiapa: employee_id is NULL .

Mari kita hasilkan jadual yang diperbetulkan , di mana kita memberikan semua tugas tergantung kepada pengarah (ID beliau = 4).

Untuk melakukan ini, kami menggunakan fungsi IFNULL() :

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

Dan hasil daripada pertanyaan ini:

ID ID pekerja nama tarikh akhir
1 1 Betulkan pepijat pada bahagian hadapan 2022-06-01
2 2 Betulkan pepijat pada bahagian belakang 15-06-2022
3 5 Beli kopi 2022-07-01
4 5 Beli kopi 2022-08-01
5 5 Beli kopi 2022-09-01
6 4 Bersihkan pejabat (NULL)
7 4 Nikmati kehidupan (NULL)
8 6 Nikmati kehidupan (NULL)

Sel yang diperbetulkan ditandakan dengan warna merah.

Sekarang mari kita gantikan jadual kami yang diperbetulkan ke dalam pertanyaan:

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

Daripada jadual tugasan .

Permintaan sedemikian akan kelihatan 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

Daripada perkataan tugas , kami menulis kurungan dan meletakkan badan permintaan di dalamnya.

Ngomong-ngomong, alias t (alias) untuk pertanyaan bersarang sangat berguna. Pertanyaan bersarang, tidak seperti jadual, tidak mempunyai namanya sendiri, jadi alias sangat tidak sesuai.

Dan inilah hasil daripada pertanyaan sedemikian:

ID nama pekerjaan gaji umur tarikh menyertai ID ID pekerja nama
1 Ivanov Ivan Pengaturcara 100000 25 30-06-2012 1 1 Betulkan pepijat pada bahagian hadapan
2 Petrov Petr Pengaturcara 80000 23 2013-08-12 2 2 Betulkan pepijat pada bahagian belakang
4 Rabinovich Moisha Pengarah 200000 35 12-05-2015 6 4 Bersihkan pejabat
4 Rabinovich Moisha Pengarah 200000 35 12-05-2015 7 4 Nikmati kehidupan
5 Kirienko Anastasia Pengurus pejabat 40000 25 2015-10-10 4 5 Beli kopi
5 Kirienko Anastasia Pengurus pejabat 40000 25 2015-10-10 5 5 Beli kopi
5 Kirienko Anastasia Pengurus pejabat 40000 25 2015-10-10 3 5 Beli kopi
6 Vaska kucing 1000 3 2018-11-11 8 6 Nikmati kehidupan

Pengarah kami mempunyai tugas untuk "membersihkan pejabat", saya rasa dia akan segera mencari seseorang untuk mewakilkannya :) Menggunakan operator WITH

Ngomong-ngomong, bermula dengan versi 8 MySQL, anda tidak perlu lagi meletakkan semua subkueri anda di dalam pertanyaan terakhir. Mereka boleh dilakukan secara berasingan. Untuk ini, pernyataan WITH digunakan .

Ia membolehkan anda membuat jadual maya (bernama pertanyaan) dan penampilannya diberikan oleh templat:

WITH Name AS (request) 

Selalunya terdapat masa apabila subkueri anda mempunyai lajur tidak bernama, seperti COUNT(*), yang anda belum berikan nama unik. Dalam kes ini, pernyataan WITH mempunyai pilihan untuk menentukan nama lajur baharu untuk subquery.

Bentuk kedua diberikan oleh templat:

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

Anda boleh menggunakan seberapa banyak jadual maya (pertanyaan bernama) yang anda mahu dan merujuk satu sama lain di dalamnya. Bentuk umum permintaan anda akan mempunyai sesuatu seperti ini:

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

Sekarang mari kita ambil pertanyaan menakutkan kami:

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 semula 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 boleh melakukannya tanpa nama lajur, tetapi kemudian anda perlu 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