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:

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 
   )