SQLda ichki so'rovlar
SQL tili bir so'rovni boshqa bir so'rov ichiga joylashtirishga imkon beradi. Bu juda katta va murakkab narsa qiladigan bitta katta so'rov yozishga imkoniyat beradi, ammo kodning o'qilishi ancha qiyinlashadi.
Ichki so'rovlar qaytaradigan qiymatlar soniga qarab ularni qo'llash mumkin bo'lgan joy o'zgaradi. Umumiy holda uchta variant mavjud:
- Ichki so'rov bitta yagona qiymat qaytaradi (bitta ustun va bitta qator).
- Ichki so'rov qiymatlar ro'yxatini qaytaradi (bitta ustunli jadval).
- Ichki so'rov jadvalni qaytaradi (ko'p ustunlar, har qanday miqdordagi qatorlar).
Keling, har bir holat uchun bitta misolni ko'rib chiqaylik.
Skalyar natijali ichki so'rov
Keling, kompaniyamizdagi o'rtacha maoshdan yuqori bo'lgan employee jadvalidan barcha xodimlarni topamiz. Buni qanday qilamiz?
Agar oldindan ma'lum bo'lgan o'rtacha maoshni bilsak, xodimlarni osonlik bilan filtrlay olamiz. Shu bilan birga biz allaqachon kompaniya xodimlarining o'rtacha maoshini hisoblash imkonini beruvchi so'rov yozgan edik. Uni eslaylik:
SELECT AVG(salary) FROM employee
O'shanda MySQL bizga 76833.3333 qiymatini qaytardi.
Endi o'rtacha maoshdan yuqori bo'lgan barcha xodimlarning ro'yxatini qanday topish mumkin? Bu juda oson:
SELECT * FROM employee WHERE salary > 76833.3333
Bu so'rovning natijasi quyidagicha bo'ladi:
id | name | occupation | salary |
---|---|---|---|
1 | Ivanov Ivan | Dasturchi | 100000 |
2 | Petrov Petr | Dasturchi | 80000 |
4 | Rabinovich Moysha | Direktor | 200000 |
Endi ikkala so'rovni birlashtirib, 76833 qiymati o'rniga birinchi so'rovni qo'yamiz:
SELECT * FROM employee WHERE salary > (SELECT AVG(salary) FROM employee)
Bu so'rovning natijasi ham xuddi shunday bo'ladi:
id | name | occupation | salary |
---|---|---|---|
1 | Ivanov Ivan | Dasturchi | 100000 |
2 | Petrov Petr | Dasturchi | 80000 |
4 | Rabinovich Moysha | Direktor | 200000 |
Qiymatlar ro'yxatiga ega ichki so'rov
Eslaysanmi, uzoq vaqt oldin bizda bir jadvaldan boshqa jadvalda mos keladigan yozuvlar yo'qligini topish masalasi bor edi?
U yerda shunaqa rasm ham bor edi:

Agar adashmasam, topshiriq quyidagicha edi: employee jadvalidan task jadvalida vazifalari yo'q bo'lgan xodimlarni ko'rsating.
Keling, bu muammoni ham ikki bosqichda yechamiz.
Avval task jadvalidagi vazifalari bor xodimlarning idlarini qaytaradigan so'rov yozamiz. Faqat ikki narsani unutmang:
- duplikatlarni olib tashlang – DISTINCT kalit so'zidan foydalandik.
- NULL qiymatlarni natijadan olib tashlang.
SELECT DISTINCT employee_id FROM task WHERE employee_id IS NOT NULL
Mana, biz bunday so'rovning chiroyli natijasini oldik:
employee_id |
---|
1 |
2 |
5 |
4 |
6 |
Qulaylik uchun uni vaqtincha ketma-ketlik shaklida yozamiz: 1,2,5,4,6. Endi ikkinchi so'rovni yozamiz – employee jadvalidagi so'rov, u birinchi ro'yxatda yo'q bo'lgan xodimlarning ro'yxatini qaytaradi:
SELECT * FROM employee WHERE id NOT IN (1,2,5,4,6)
Bu so'rovning natijasi quyidagicha bo'ladi:
id | name | occupation | salary | age | join_date |
---|---|---|---|---|---|
3 | Ivanov Sergey | Testlovchi | 40000 | 30 | 2014-01-01 |
Endi, avvalgi misolda bo'lgani kabi, ikkala so'rovni birlashtirishimiz mumkin, shunchaki birinchi so'rovning tanasi o'rniga id ro'yxatini qo'yishimiz kifoya.
SELECT * FROM employee WHERE id NOT IN ( SELECT DISTINCT employee_id FROM task WHERE employee_id IS NOT NULL )
GO TO FULL VERSION