Subquery retourneert een tabel
En tot slot, de derde optie is wanneer de subquery de hele tabel retourneert. Dit is de meest voorkomende optie.
Heel vaak zijn er situaties waarin we een bepaalde tabel een beetje willen aanpassen. En voeg dan pas (met behulp van de JOIN ON-operator) de gecorrigeerde tabel toe aan een andere.
Laten we beginnen met het eenvoudigste geval, waarbij we twee tabellen hebben samengevoegd met een JOIN:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
En zoals u zich waarschijnlijk herinnert, zijn er taken in de takentabel die aan niemand zijn toegewezen: employee_id is NULL .
Laten we een gecorrigeerde tabel genereren , waarin we alle hangende taken toewijzen aan de regisseur (zijn ID = 4).
Om dit te doen, gebruiken we de functie IFNULL() :
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task
En het resultaat van deze vraag:
ID kaart | medewerker_id | naam | deadline |
---|---|---|---|
1 | 1 | Los een bug op de frontend op | 01-06-2022 |
2 | 2 | Los een bug op de backend op | 2022-06-15 |
3 | 5 | Koop koffie | 01-07-2022 |
4 | 5 | Koop koffie | 01-08-2022 |
5 | 5 | Koop koffie | 01-09-2022 |
6 | 4 | Ruim het kantoor op | (NUL) |
7 | 4 | Geniet van het leven | (NUL) |
8 | 6 | Geniet van het leven | (NUL) |
De gecorrigeerde cel is rood gemarkeerd.
Laten we nu onze gecorrigeerde tabel vervangen door de query:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
In plaats van de taaktabel .
Zo'n verzoek ziet er ongeveer zo uit:
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
In plaats van het woord taak , hebben we haakjes geschreven en de hoofdtekst van het verzoek erin geplaatst.
Trouwens, de alias t (alias) voor de geneste query was erg handig. Een geneste query heeft, in tegenstelling tot een tabel, geen eigen naam, dus de alias is erg misplaatst.
En hier is het resultaat van zo'n vraag:
ID kaart | naam | bezigheid | salaris | leeftijd | join_date | ID kaart | medewerker_id | naam |
---|---|---|---|---|---|---|---|---|
1 | Ivanov Ivan | Programmeur | 100000 | 25 | 2012-06-30 | 1 | 1 | Los een bug op de frontend op |
2 | Petrov Petr | Programmeur | 80000 | 23 | 2013-08-12 | 2 | 2 | Los een bug op de backend op |
4 | Rabinovich Moisha | Regisseur | 200000 | 35 | 2015-05-12 | 6 | 4 | Ruim het kantoor op |
4 | Rabinovich Moisha | Regisseur | 200000 | 35 | 2015-05-12 | 7 | 4 | Geniet van het leven |
5 | Kirienko Anastasia | Officemanager | 40000 | 25 | 2015-10-10 | 4 | 5 | Koop koffie |
5 | Kirienko Anastasia | Officemanager | 40000 | 25 | 2015-10-10 | 5 | 5 | Koop koffie |
5 | Kirienko Anastasia | Officemanager | 40000 | 25 | 2015-10-10 | 3 | 5 | Koop koffie |
6 | Vaska | kat | 1000 | 3 | 2018-11-11 | 8 | 6 | Geniet van het leven |
Onze directeur heeft de taak om "het kantoor op te ruimen", ik denk dat hij snel iemand zal vinden om het aan te delegeren :) De operator WITH gebruiken
Trouwens, vanaf versie 8 van MySQL hoef je niet langer al je subquery's in de uiteindelijke query te plaatsen. Ze kunnen afzonderlijk worden uitgevoerd. Hiervoor wordt het WITH statement gebruikt .
Hiermee kunt u een virtuele tabel maken (genaamde query) en het uiterlijk wordt bepaald door een sjabloon:
WITH Name AS (request)
Het komt vaak voor dat uw subquery naamloze kolommen heeft, zoals COUNT(*), waaraan u geen unieke naam hebt toegewezen. In dit geval heeft de WITH-instructie de optie om nieuwe kolomnamen voor de subquery op te geven.
De tweede vorm wordt gegeven door de sjabloon:
WITH Name(column1, column2, …) AS (request)
U kunt zoveel virtuele tabellen (benoemde query's) gebruiken als u wilt en daarin naar elkaar verwijzen. De algemene vorm van uw verzoek ziet er ongeveer zo uit:
WITH name1 AS (request1),
name2 AS (request2),
name3 AS (request3)
SELECT * FROM name1 JOIN name2 ON …
Laten we nu onze enge vraag nemen:
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
En herschrijf het met behulp van de WITH-instructie:
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
Of u kunt het doen zonder kolomnamen, maar dan moet u een alias opgeven voor de IFNULL()-functie:
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