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