Pertanyaan bersarang dalam SQL

Bahasa SQL membolehkan anda menyusun satu pertanyaan dalam pertanyaan lain. Ini memungkinkan untuk menulis satu pertanyaan yang sangat besar yang akan melakukan sesuatu yang besar dan kompleks, walaupun kebolehbacaan kod itu sangat berkurangan.

Bergantung pada bilangan nilai yang dikembalikan oleh subkueri, kawasan di mana ia boleh digunakan berubah. Terdapat tiga pilihan secara keseluruhan:

  • Subquery mengembalikan satu nilai tunggal (satu lajur dan satu baris).
  • Subquery mengembalikan senarai nilai (jadual dengan satu lajur).
  • Subquery mengembalikan jadual (banyak lajur, sebarang bilangan baris).

Mari lihat satu contoh untuk setiap kes.

Subkueri dengan hasil skalar

Mari cari senarai semua pekerja kami dari jadual pekerja yang gajinya lebih tinggi daripada purata untuk syarikat. Bagaimana kita boleh melakukannya?

Kita boleh menapis pekerja dengan mudah dengan membandingkan gaji mereka dengan purata jika kita mengetahuinya terlebih dahulu. Pada masa yang sama, kami telah pun menulis pertanyaan yang membolehkan kami mengira purata gaji pekerja syarikat. Mari kita ingat:

SELECT AVG(salary) FROM employee 

Kemudian MySQL mengembalikan nilai kepada kami: 76833.3333 .

Bagaimana sekarang untuk mencari senarai semua pekerja yang gajinya melebihi purata? Ia juga sangat mudah:

 SELECT * FROM employee 
   WHERE salary > 76833.3333 

Hasil daripada pertanyaan ini ialah:

ID nama pekerjaan gaji
1 Ivanov Ivan Pengaturcara 100000
2 Petrov Petr Pengaturcara 80000
4 Rabinovich Moisha Pengarah 200000

Dan sekarang kita hanya menggabungkan kedua-dua permintaan dengan menggantikan permintaan pertama dan bukannya nilai 76833:

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

Keputusan pertanyaan ini akan sama:

ID nama pekerjaan gaji
1 Ivanov Ivan Pengaturcara 100000
2 Petrov Petr Pengaturcara 80000
4 Rabinovich Moisha Pengarah 200000

Subquery dengan senarai nilai

Adakah anda masih ingat suatu ketika dahulu kita mempunyai tugas - untuk mencari semua rekod dari satu jadual yang tiada rekod yang sepadan daripada yang lain?

Terdapat juga gambar ini:

Jika tidak silap saya, tugasnya adalah seperti berikut: paparkan senarai semua pekerja dari jadual pekerja yang tiada tugas dalam jadual tugas .

Mari kita juga mencari penyelesaian dalam dua langkah.

Mula-mula, mari tulis pertanyaan yang akan mengembalikan id semua pekerja yang mempunyai tugas dalam jadual tugas. Hanya ingat dua perkara:

  • alih keluar pendua - gunakan kata kunci DISTINCT.
  • keluarkan nilai NULL daripada hasilnya.
SELECT DISTINCT employee_id FROM task 
   WHERE employee_id IS NOT NULL

Dan di sini kami mendapat hasil yang indah dari permintaan sedemikian:

ID pekerja
1
2
5
4
6

Mari kita tuliskannya sementara untuk kemudahan sebagai urutan: 1,2,5,4,6. Sekarang mari tulis pertanyaan kedua - ke jadual pekerja, yang akan mengembalikan senarai pekerja yang idnya tidak terkandung dalam senarai pertama:

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

Dan hasil daripada pertanyaan ini:

ID nama pekerjaan gaji umur tarikh menyertai
3 Ivanov Sergey Penguji 40000 tiga puluh 2014-01-01

Dan sekarang, seperti dalam contoh sebelumnya, anda boleh menggabungkan kedua-dua permintaan dengan hanya menggantikan badan permintaan pertama dan bukannya senarai id.

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