Geneste query's in SQL
Met de SQL-taal kunt u een query in een andere query nesten. Dit maakt het mogelijk om één zeer grote query te schrijven die iets groots en ingewikkelds zal doen, hoewel de leesbaarheid van de code sterk wordt verminderd.
Afhankelijk van hoeveel waarden worden geretourneerd door subquery's, verandert het gebied waar ze kunnen worden toegepast. Er zijn in totaal drie opties:
- De subquery retourneert één enkele waarde (één kolom en één rij).
- De subquery retourneert een lijst met waarden (een tabel met één kolom).
- De subquery retourneert een tabel (veel kolommen, een willekeurig aantal rijen).
Laten we voor elk geval een voorbeeld bekijken.
Subquery met scalair resultaat
Laten we een lijst zoeken van al onze werknemers uit de werknemerstabel wiens salaris hoger is dan het gemiddelde voor het bedrijf. Hoe kunnen we het doen?
We kunnen medewerkers eenvoudig filteren door hun salaris te vergelijken met het gemiddelde als we dat van tevoren weten. Tegelijkertijd hebben we al een query geschreven waarmee we het gemiddelde salaris van de werknemers van het bedrijf kunnen berekenen. Laten we het onthouden:
SELECT AVG(salary) FROM employee
Vervolgens heeft MySQL ons de waarde geretourneerd: 76833.3333 .
Hoe vind je nu een lijst van alle werknemers met een bovengemiddeld salaris? Het is ook heel simpel:
SELECT * FROM employee
WHERE salary > 76833.3333
Het resultaat van deze query zal zijn:
ID kaart | naam | bezigheid | salaris |
---|---|---|---|
1 | Ivanov Ivan | Programmeur | 100000 |
2 | Petrov Petr | Programmeur | 80000 |
4 | Rabinovich Moisha | Regisseur | 200000 |
En nu combineren we beide verzoeken door het eerste verzoek te vervangen in plaats van de waarde 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
Het resultaat van deze query is hetzelfde:
ID kaart | naam | bezigheid | salaris |
---|---|---|---|
1 | Ivanov Ivan | Programmeur | 100000 |
2 | Petrov Petr | Programmeur | 80000 |
4 | Rabinovich Moisha | Regisseur | 200000 |
Subquery met lijst met waarden
Herinner je je dat we ooit een taak hadden - om alle records van de ene tabel te vinden waarvoor er geen overeenkomstige records van een andere zijn?
Er was ook deze foto:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
Als ik me niet vergis, is de taak als volgt: geef een lijst weer van alle werknemers uit de werknemerstabel waarvoor er geen taken in de takentabel staan .
Laten we ook een oplossing vinden in twee stappen.
Laten we eerst een query schrijven die de id retourneert van alle werknemers die taken in de taaktabel hebben. Onthoud gewoon twee dingen:
- verwijder duplicaten - gebruik het sleutelwoord DISTINCT.
- verwijder NULL-waarden uit het resultaat.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
En hier kregen we een prachtig resultaat van zo'n verzoek:
medewerker_id |
---|
1 |
2 |
5 |
4 |
6 |
Laten we het voor het gemak tijdelijk opschrijven als een reeks: 1,2,5,4,6. Laten we nu een tweede query schrijven - naar de werknemerstabel, die een lijst zal retourneren van werknemers wiens ID niet in de eerste lijst staat:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
En het resultaat van deze vraag:
ID kaart | naam | bezigheid | salaris | leeftijd | join_date |
---|---|---|---|---|---|
3 | Ivanov Sergej | Tester | 40000 | dertig | 01-01-2014 |
En nu kunt u, net als in het vorige voorbeeld, beide verzoeken combineren door simpelweg de hoofdtekst van het eerste verzoek te vervangen in plaats van de id-lijst.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)
GO TO FULL VERSION