Mga nested na query sa SQL

Binibigyang-daan ka ng wikang SQL na mag-nest ng isang query sa loob ng isa pang query. Ginagawa nitong posible na magsulat ng isang napakalaking query na gagawa ng isang bagay na malaki at kumplikado, kahit na ang pagiging madaling mabasa ng code ay lubhang nabawasan.

Depende sa kung gaano karaming mga halaga ang ibinalik ng mga subquery, ang lugar kung saan maaaring ilapat ang mga ito ay nagbabago. Mayroong tatlong mga opsyon sa kabuuan:

  • Ang subquery ay nagbabalik ng isang solong halaga (isang hanay at isang hilera).
  • Ang subquery ay nagbabalik ng isang listahan ng mga halaga (isang talahanayan na may isang haligi).
  • Ang subquery ay nagbabalik ng isang talahanayan (maraming mga hanay, anumang bilang ng mga hilera).

Tingnan natin ang isang halimbawa para sa bawat kaso.

Subquery na may scalar na resulta

Maghanap tayo ng listahan ng lahat ng ating mga empleyado mula sa talahanayan ng empleyado na ang suweldo ay mas mataas kaysa sa karaniwan para sa kumpanya. Paano natin ito magagawa?

Madali nating ma-filter ang mga empleyado sa pamamagitan ng paghahambing ng kanilang suweldo sa average kung alam natin ito nang maaga. Kasabay nito, nakapagsulat na kami ng query na nagbibigay-daan sa amin na kalkulahin ang average na suweldo ng mga empleyado ng kumpanya. Tandaan natin ito:

SELECT AVG(salary) FROM employee 

Pagkatapos ay ibinalik sa amin ng MySQL ang halaga: 76833.3333 .

Paano ngayon makahanap ng isang listahan ng lahat ng mga empleyado na ang suweldo ay higit sa average? Ito rin ay napaka-simple:

 SELECT * FROM employee 
   WHERE salary > 76833.3333 

Ang magiging resulta ng query na ito ay:

id pangalan hanapbuhay suweldo
1 Ivanov Ivan Programmer 100000
2 Petrov Petr Programmer 80000
4 Rabinovich Moisha Direktor 200000

At ngayon pinagsasama na lang namin ang parehong mga kahilingan sa pamamagitan ng pagpapalit sa unang kahilingan sa halip na ang halagang 76833:

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

Magiging pareho ang resulta ng query na ito:

id pangalan hanapbuhay suweldo
1 Ivanov Ivan Programmer 100000
2 Petrov Petr Programmer 80000
4 Rabinovich Moisha Direktor 200000

Subquery na may listahan ng mga halaga

Naaalala mo ba noong unang panahon na mayroon tayong gawain - hanapin ang lahat ng mga talaan mula sa isang talahanayan kung saan walang katumbas na mga talaan mula sa iba?

Nagkaroon din ng ganitong larawan:

Kung hindi ako nagkakamali, ang gawain ay ang mga sumusunod: magpakita ng listahan ng lahat ng empleyado mula sa talahanayan ng empleyado kung saan walang mga gawain sa talahanayan ng gawain .

Maghanap din tayo ng solusyon sa dalawang hakbang.

Una, magsulat tayo ng query na magbabalik ng id ng lahat ng empleyado na may mga gawain sa talahanayan ng gawain. Tandaan lamang ang dalawang bagay:

  • alisin ang mga duplicate - gamitin ang DISTINCT na keyword.
  • alisin ang mga halaga ng NULL mula sa resulta.
SELECT DISTINCT employee_id FROM task 
   WHERE employee_id IS NOT NULL

At dito nakakuha kami ng magandang resulta ng naturang kahilingan:

employee_id
1
2
5
4
6

Pansamantala nating isulat ito para sa kaginhawahan bilang isang sequence: 1,2,5,4,6. Ngayon magsulat tayo ng pangalawang query - sa talahanayan ng empleyado, na magbabalik ng isang listahan ng mga empleyado na ang id ay hindi nakapaloob sa unang listahan:

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

At ang resulta ng query na ito:

id pangalan hanapbuhay suweldo edad Sumali sa date
3 Ivanov Sergey Tester 40000 tatlumpu 2014-01-01

At ngayon, tulad ng sa nakaraang halimbawa, maaari mong pagsamahin ang parehong mga kahilingan sa pamamagitan lamang ng pagpapalit sa katawan ng unang kahilingan sa halip na sa listahan ng id.

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