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
GO TO FULL VERSION