Indlejrede forespørgsler i SQL
SQL-sproget giver dig mulighed for at indlejre én forespørgsel i en anden forespørgsel. Dette gør det muligt at skrive en meget stor forespørgsel, der vil gøre noget stort og komplekst, selvom læsbarheden af koden er stærkt reduceret.
Afhængigt af hvor mange værdier der returneres af underforespørgsler, ændres området, hvor de kan anvendes. Der er tre muligheder i alt:
- Underforespørgslen returnerer én enkelt værdi (én kolonne og én række).
- Underforespørgslen returnerer en liste over værdier (en tabel med én kolonne).
- Underforespørgslen returnerer en tabel (mange kolonner, et vilkårligt antal rækker).
Lad os se på et eksempel for hver sag.
Underforespørgsel med skalært resultat
Lad os finde en liste over alle vores medarbejdere fra medarbejdertabellen, hvis løn er højere end gennemsnittet for virksomheden. Hvordan kan vi gøre det?
Vi kan nemt filtrere medarbejdere ved at sammenligne deres løn med gennemsnittet, hvis vi ved det på forhånd. Samtidig har vi allerede skrevet en forespørgsel, der giver os mulighed for at beregne gennemsnitslønnen for virksomhedens ansatte. Lad os huske det:
SELECT AVG(salary) FROM employee
Så returnerede MySQL os værdien: 76833.3333 .
Hvordan finder man nu en liste over alle medarbejdere, hvis løn er over gennemsnittet? Det er også meget enkelt:
SELECT * FROM employee
WHERE salary > 76833.3333
Resultatet af denne forespørgsel vil være:
id | navn | beskæftigelse | løn |
---|---|---|---|
1 | Ivanov Ivan | Programmer | 100.000 |
2 | Petrov Petr | Programmer | 80.000 |
4 | Rabinovich Moisha | Direktør | 200.000 |
Og nu kombinerer vi bare begge anmodninger ved at erstatte den første anmodning i stedet for værdien 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
Resultatet af denne forespørgsel vil være det samme:
id | navn | beskæftigelse | løn |
---|---|---|---|
1 | Ivanov Ivan | Programmer | 100.000 |
2 | Petrov Petr | Programmer | 80.000 |
4 | Rabinovich Moisha | Direktør | 200.000 |
Underforespørgsel med liste over værdier
Kan du huske, at vi engang havde en opgave - at finde alle poster fra en tabel, som der ikke er tilsvarende poster til fra en anden?
Der var også dette billede:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
Hvis jeg ikke tager fejl, er opgaven som følger: vis en liste over alle medarbejdere fra medarbejdertabellen, som der ikke er opgaver til i opgavetabellen .
Lad os også finde en løsning i to trin.
Lad os først skrive en forespørgsel, der returnerer id'et for alle medarbejdere, der har opgaver i opgavetabellen. Bare husk to ting:
- fjern dubletter - brug søgeordet DISTINCT.
- fjern NULL-værdier fra resultatet.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
Og her fik vi et smukt resultat af sådan en anmodning:
Medarbejder-ID |
---|
1 |
2 |
5 |
4 |
6 |
Lad os midlertidigt skrive det ned for nemheds skyld som en sekvens: 1,2,5,4,6. Lad os nu skrive en anden forespørgsel - til medarbejdertabellen, som vil returnere en liste over medarbejdere, hvis id ikke er indeholdt i den første liste:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
Og resultatet af denne forespørgsel:
id | navn | beskæftigelse | løn | alder | join_date |
---|---|---|---|---|---|
3 | Ivanov Sergey | Tester | 40.000 | tredive | 2014-01-01 |
Og nu, som i det foregående eksempel, kan du kombinere begge anmodninger ved blot at erstatte brødteksten i den første anmodning i stedet for id-listen.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)
GO TO FULL VERSION