Underforespørgsel returnerer en tabel

Og endelig er den tredje mulighed, når underforespørgslen returnerer hele tabellen. Dette er den mest almindelige mulighed.

Meget ofte er der situationer, hvor vi ønsker at justere et bestemt bord lidt. Og først derefter forbinde (ved hjælp af JOIN ON-operatoren) den korrigerede tabel med en anden.

Lad os starte med det enkleste tilfælde, hvor vi forenede to tabeller med en JOIN:

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

Og som du sikkert husker, er der opgaver i opgavetabellen , som ikke er tildelt nogen: medarbejder_id er NULL .

Lad os generere en korrigeret tabel , hvor vi tildeler alle de hængende opgaver til direktøren (hans ID = 4).

For at gøre dette bruger vi IFNULL() -funktionen :

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

Og resultatet af denne forespørgsel:

id Medarbejder-ID navn deadline
1 1 Ret en fejl på frontend 2022-06-01
2 2 Ret en fejl på backend 2022-06-15
3 5 Køb kaffe 2022-07-01
4 5 Køb kaffe 2022-08-01
5 5 Køb kaffe 2022-09-01
6 4 Ryd op på kontoret (NUL)
7 4 Nyd livet (NUL)
8 6 Nyd livet (NUL)

Den korrigerede celle er markeret med rødt.

Lad os nu erstatte vores korrigerede tabel med forespørgslen:

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

I stedet for opgavetabellen .

En sådan anmodning ville se sådan ud:

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

I stedet for ordet opgave skrev vi parenteser og placerede anmodningsteksten i dem.

I øvrigt var aliaset t (alias) for den indlejrede forespørgsel meget nyttigt. En indlejret forespørgsel, i modsætning til en tabel, har ikke sit eget navn, så aliaset er meget malplaceret.

Og her er resultatet af en sådan forespørgsel:

id navn beskæftigelse løn alder join_date id Medarbejder-ID navn
1 Ivanov Ivan Programmer 100.000 25 2012-06-30 1 1 Ret en fejl på frontend
2 Petrov Petr Programmer 80.000 23 2013-08-12 2 2 Ret en fejl på backend
4 Rabinovich Moisha Direktør 200.000 35 2015-05-12 6 4 Ryd op på kontoret
4 Rabinovich Moisha Direktør 200.000 35 2015-05-12 7 4 Nyd livet
5 Kirienko Anastasia Kontorchef 40.000 25 2015-10-10 4 5 Køb kaffe
5 Kirienko Anastasia Kontorchef 40.000 25 2015-10-10 5 5 Køb kaffe
5 Kirienko Anastasia Kontorchef 40.000 25 2015-10-10 3 5 Køb kaffe
6 Vaska kat 1000 3 2018-11-11 8 6 Nyd livet

Vores direktør har til opgave at "rydde op på kontoret", jeg tror han hurtigt finder nogen at uddelegere det til :) Bruger WITH-operatøren

Fra og med version 8 af MySQL behøver du forresten ikke længere at lægge alle dine underforespørgsler lige inde i den endelige forespørgsel. De kan udføres separat. Til dette bruges WITH-sætningen .

Det giver dig mulighed for at oprette en virtuel tabel (navngivet forespørgsel), og dens udseende er givet af en skabelon:

WITH Name AS (request) 

Der er ofte tidspunkter, hvor din underforespørgsel har unavngivne kolonner, såsom COUNT(*), som du ikke har tildelt et unikt navn. I dette tilfælde har WITH-sætningen mulighed for at angive nye kolonnenavne til underforespørgslen.

Dens anden form er givet af skabelonen:

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

Du kan bruge så mange virtuelle tabeller (navngivne forespørgsler), som du vil, og henvise til hinanden i dem. Den generelle form for din anmodning vil have noget som dette:

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

Lad os nu tage vores skræmmende forespørgsel:

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  

Og omskriv det ved hjælp af WITH-sætningen:

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

Eller du kan undvære kolonnenavne, men så bliver du nødt til at angive et alias for IFNULL()-funktionen:

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