Subinterogarea returnează un tabel
Și, în sfârșit, a treia opțiune este atunci când subinterogarea returnează întregul tabel. Aceasta este cea mai comună opțiune.
De foarte multe ori există situații în care dorim să ajustăm puțin o anumită masă. Și abia apoi unește (folosind operatorul JOIN ON) tabelul corectat cu altul.
Să începem cu cel mai simplu caz, în care am unit două tabele cu un JOIN:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
Și după cum probabil vă amintiți, există sarcini în tabelul de activități care nu sunt atribuite nimănui: employee_id este NULL .
Să generăm un tabel corectat , în care atribuim toate sarcinile suspendate directorului (ID-ul lui = 4).
Pentru a face acest lucru, folosim funcția IFNULL() :
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task
Și rezultatul acestei interogări:
id | card de identitate al angajatului | Nume | Termen limită |
---|---|---|---|
1 | 1 | Remediați o eroare pe front-end | 2022-06-01 |
2 | 2 | Remediați o eroare pe backend | 2022-06-15 |
3 | 5 | Cumpără cafea | 2022-07-01 |
4 | 5 | Cumpără cafea | 2022-08-01 |
5 | 5 | Cumpără cafea | 2022-09-01 |
6 | 4 | Curățați biroul | (NUL) |
7 | 4 | Bucură-te de viață | (NUL) |
8 | 6 | Bucură-te de viață | (NUL) |
Celula corectată este marcată cu roșu.
Acum să înlocuim tabelul nostru corectat în interogare:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
În loc de tabelul de sarcini .
O astfel de cerere ar arăta cam așa:
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
În loc de cuvântul task , am scris paranteze și am plasat corpul cererii în ele.
Apropo, alias-ul t (alias) pentru interogarea imbricată a fost foarte util. O interogare imbricată, spre deosebire de un tabel, nu are propriul nume, așa că alias-ul este foarte deplasat.
Și iată rezultatul unei astfel de interogări:
id | Nume | ocupaţie | salariu | vârstă | Data înscrierii | id | card de identitate al angajatului | Nume |
---|---|---|---|---|---|---|---|---|
1 | Ivanov Ivan | Programator | 100000 | 25 | 30-06-2012 | 1 | 1 | Remediați o eroare pe front-end |
2 | Petrov Petr | Programator | 80000 | 23 | 12-08-2013 | 2 | 2 | Remediați o eroare pe backend |
4 | Rabinovici Moisha | Director | 200000 | 35 | 2015-05-12 | 6 | 4 | Curățați biroul |
4 | Rabinovici Moisha | Director | 200000 | 35 | 2015-05-12 | 7 | 4 | Bucură-te de viață |
5 | Kirienko Anastasia | Manager de birou | 40000 | 25 | 2015-10-10 | 4 | 5 | Cumpără cafea |
5 | Kirienko Anastasia | Manager de birou | 40000 | 25 | 2015-10-10 | 5 | 5 | Cumpără cafea |
5 | Kirienko Anastasia | Manager de birou | 40000 | 25 | 2015-10-10 | 3 | 5 | Cumpără cafea |
6 | Vaska | pisică | 1000 | 3 | 2018-11-11 | 8 | 6 | Bucură-te de viață |
Directorul nostru are sarcina de a „curăța biroul”, cred că va găsi rapid pe cineva căruia să-l delege :) Folosind operatorul WITH
Apropo, începând cu versiunea 8 a MySQL, nu mai trebuie să puneți toate subinterogările chiar în interogarea finală. Ele pot fi efectuate separat. Pentru aceasta se folosește instrucțiunea WITH .
Vă permite să creați un tabel virtual (denumit interogare) iar aspectul acestuia este dat de un șablon:
WITH Name AS (request)
Există adesea momente în care subinterogarea dvs. are coloane fără nume, cum ar fi COUNT(*), cărora nu le-ați atribuit un nume unic. În acest caz, instrucțiunea WITH are opțiunea de a specifica nume de coloane noi pentru subinterogare.
A doua formă este dată de șablon:
WITH Name(column1, column2, …) AS (request)
Puteți folosi câte tabele virtuale (interogări denumite) doriți și vă puteți referi unul la celălalt în ele. Forma generală a cererii dvs. va avea ceva de genul acesta:
WITH name1 AS (request1),
name2 AS (request2),
name3 AS (request3)
SELECT * FROM name1 JOIN name2 ON …
Acum să luăm întrebarea noastră înfricoșătoare:
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 rescrieți-l folosind instrucțiunea 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
Sau puteți face fără nume de coloane, dar apoi va trebui să specificați un alias pentru funcția 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