Underspørring returnerer en tabell
Og til slutt, det tredje alternativet er når underspørringen returnerer hele tabellen. Dette er det vanligste alternativet.
Svært ofte er det situasjoner når vi ønsker å finpusse et bestemt bord litt. Og først deretter koble sammen (ved hjelp av JOIN ON-operatoren) den korrigerte tabellen med en annen.
La oss starte med det enkleste tilfellet, der vi slo sammen to tabeller med en JOIN:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
Og som du sikkert husker, er det oppgaver i oppgavetabellen som ikke er tildelt noen: ansatt_id er NULL .
La oss generere en korrigert tabell , der vi tildeler alle hengeoppgavene til regissøren (hans ID = 4).
For å gjøre dette bruker vi IFNULL() -funksjonen :
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task
Og resultatet av denne spørringen:
id | Ansatt ID | Navn | frist |
---|---|---|---|
1 | 1 | Rett opp en feil på frontend | 2022-06-01 |
2 | 2 | Rett opp en feil på backend | 2022-06-15 |
3 | 5 | Kjøp kaffe | 2022-07-01 |
4 | 5 | Kjøp kaffe | 2022-08-01 |
5 | 5 | Kjøp kaffe | 2022-09-01 |
6 | 4 | Rydd opp på kontoret | (NULL) |
7 | 4 | Nyt livet | (NULL) |
8 | 6 | Nyt livet | (NULL) |
Den korrigerte cellen er markert med rødt.
La oss nå erstatte vår korrigerte tabell i spørringen:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
I stedet for oppgavetabellen .
En slik forespørsel vil se omtrent slik ut:
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 oppgave skrev vi parenteser og plasserte forespørselsteksten i dem.
Forresten, aliaset t (alias) for den nestede spørringen var veldig nyttig. En nestet spørring, i motsetning til en tabell, har ikke sitt eget navn, så aliaset er veldig malplassert.
Og her er resultatet av en slik spørring:
id | Navn | okkupasjon | lønn | alder | join_date | id | Ansatt ID | Navn |
---|---|---|---|---|---|---|---|---|
1 | Ivanov Ivan | Programmerer | 100 000 | 25 | 2012-06-30 | 1 | 1 | Rett opp en feil på frontend |
2 | Petrov Petr | Programmerer | 80 000 | 23 | 2013-08-12 | 2 | 2 | Rett opp en feil på backend |
4 | Rabinovich Moisha | Regissør | 200 000 | 35 | 2015-05-12 | 6 | 4 | Rydd opp på kontoret |
4 | Rabinovich Moisha | Regissør | 200 000 | 35 | 2015-05-12 | 7 | 4 | Nyt livet |
5 | Kirienko Anastasia | Kontorsjef | 40 000 | 25 | 2015-10-10 | 4 | 5 | Kjøp kaffe |
5 | Kirienko Anastasia | Kontorsjef | 40 000 | 25 | 2015-10-10 | 5 | 5 | Kjøp kaffe |
5 | Kirienko Anastasia | Kontorsjef | 40 000 | 25 | 2015-10-10 | 3 | 5 | Kjøp kaffe |
6 | Vaska | katt | 1000 | 3 | 2018-11-11 | 8 | 6 | Nyt livet |
Direktøren vår har som oppgave å "rydde opp på kontoret", jeg tror han raskt finner noen å delegere det til :) Bruker WITH-operatøren
Forresten, fra og med versjon 8 av MySQL, trenger du ikke lenger å legge alle underspørringene dine rett innenfor den endelige spørringen. De kan utføres separat. For dette brukes WITH-setningen .
Den lar deg lage en virtuell tabell (kalt spørring) og dens utseende er gitt av en mal:
WITH Name AS (request)
Det er ofte når undersøket ditt har navnløse kolonner, for eksempel COUNT(*), som du ikke har tildelt et unikt navn. I dette tilfellet har WITH-setningen muligheten til å spesifisere nye kolonnenavn for underspørringen.
Den andre formen er gitt av malen:
WITH Name(column1, column2, …) AS (request)
Du kan bruke så mange virtuelle tabeller (navngitte spørringer) du vil og referere til hverandre i dem. Den generelle formen for forespørselen din vil ha noe slikt:
WITH name1 AS (request1),
name2 AS (request2),
name3 AS (request3)
SELECT * FROM name1 JOIN name2 ON …
La oss nå ta vårt skumle spørsmål:
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 skriv den om ved å bruke WITH-setningen:
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 klare deg uten kolonnenavn, men da må du spesifisere et alias for IFNULL()-funksjonen:
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