Kapslade frågor i SQL

SQL-språket låter dig kapsla en fråga i en annan fråga. Detta gör det möjligt att skriva en mycket stor fråga som kommer att göra något stort och komplext, även om kodens läsbarhet är avsevärt reducerad.

Beroende på hur många värden som returneras av underfrågor ändras området där de kan tillämpas. Det finns tre alternativ totalt:

  • Underfrågan returnerar ett enda värde (en kolumn och en rad).
  • Underfrågan returnerar en lista med värden (en tabell med en kolumn).
  • Underfrågan returnerar en tabell (många kolumner, valfritt antal rader).

Låt oss titta på ett exempel för varje fall.

Underfråga med skalärt resultat

Låt oss hitta en lista över alla våra anställda från personaltabellen vars lön är högre än genomsnittet för företaget. Hur kan vi göra det?

Vi kan enkelt filtrera anställda genom att jämföra deras lön med genomsnittet om vi vet det i förväg. Samtidigt har vi redan skrivit en fråga som gör att vi kan beräkna snittlönen för företagets anställda. Låt oss komma ihåg det:

SELECT AVG(salary) FROM employee 

Sedan returnerade MySQL oss värdet: 76833.3333 .

Hur hittar man nu en lista över alla anställda vars lön är över genomsnittet? Det är också väldigt enkelt:

 SELECT * FROM employee 
   WHERE salary > 76833.3333 

Resultatet av denna fråga blir:

id namn ockupation lön
1 Ivanov Ivan Programmerare 100 000
2 Petrov Petr Programmerare 80 000
4 Rabinovich Moisha Direktör 200 000

Och nu kombinerar vi bara båda begäranden genom att ersätta den första begäran istället för värdet 76833:

   SELECT * FROM employee 
   WHERE salary > (SELECT AVG(salary) FROM employee) 

Resultatet av denna fråga blir detsamma:

id namn ockupation lön
1 Ivanov Ivan Programmerare 100 000
2 Petrov Petr Programmerare 80 000
4 Rabinovich Moisha Direktör 200 000

Underfråga med värdelista

Kommer du ihåg att vi en gång i tiden hade en uppgift - att hitta alla poster från en tabell som det inte finns motsvarande poster för från en annan?

Det fanns även denna bild:

Om jag inte har fel så är uppgiften följande: visa en lista över alla anställda från personaltabellen för vilka det inte finns några uppgifter i uppgiftstabellen .

Låt oss också hitta en lösning i två steg.

Låt oss först skriva en fråga som returnerar id:t för alla anställda som har uppgifter i uppgiftstabellen. Kom bara ihåg två saker:

  • ta bort dubbletter - använd nyckelordet DISTINCT.
  • ta bort NULL-värden från resultatet.
SELECT DISTINCT employee_id FROM task 
   WHERE employee_id IS NOT NULL

Och här fick vi ett vackert resultat av en sådan begäran:

Anställnings-ID
1
2
5
4
6

Låt oss tillfälligt skriva ner det för bekvämlighets skull som en sekvens: 1,2,5,4,6. Låt oss nu skriva en andra fråga - till medarbetartabellen, som kommer att returnera en lista över anställda vars ID inte finns i den första listan:

SELECT * FROM employee  
WHERE id NOT IN (1,2,5,4,6)

Och resultatet av denna fråga:

id namn ockupation lön ålder join_date
3 Ivanov Sergey Testare 40 000 trettio 2014-01-01

Och nu, som i det föregående exemplet, kan du kombinera båda förfrågningarna genom att helt enkelt ersätta brödtexten i den första förfrågan istället för id-listan.

 SELECT * FROM employee 
   WHERE id NOT IN ( 
      	SELECT DISTINCT employee_id FROM task 
      	WHERE employee_id IS NOT NULL 
   )