SQL so'rovlari kattalashgani sari ularni o'qish qiyinlashadi. Ayniqsa, quyi so'rovlar (subquery) ko'paysa, so'rov qavslar ichida "yashiringan" bo'lib qoladi. Mana shu yerda WITH operatori — ya'ni umumiy jadval ifodasi (CTE, Common Table Expression) — yordamga keladi.
CTE — bu so'rov boshida e'lon qilinadigan vaqtinchalik nomlangan natija. Uni xuddi haqiqiy jadval kabi, lekin faqat shu bitta so'rov ichida ishlatish mumkin. So'rov tugashi bilan bu "jadval" yo'qoladi — ma'lumotlar bazasida hech narsa saqlanib qolmaydi.
Misollar uchun mahsulotlar jadvalidan foydalanamiz:
| id | nomi | kategoriya | narx | ombor |
|---|---|---|---|---|
| 1 | Telefon | Elektronika | 5000000 | 10 |
| 2 | Noutbuk | Elektronika | 12000000 | 5 |
| 3 | Quloqchin | Elektronika | 300000 | 50 |
| 4 | Kitob | Kitoblar | 50000 | 100 |
| 5 | Daftar | Kanstovar | 8000 | 200 |
| 6 | Ruchka | Kanstovar | 3000 | 500 |
| 7 | Stol | Mebel | 800000 | 15 |
| 8 | Stul | Mebel | 250000 | 40 |
CTE ni yozish uchun so'rovni WITH so'zi bilan boshlaymiz, unga nom beramiz va AS ( ... ) qavslari ichiga vaqtinchalik jadvalni hosil qiluvchi so'rovni yozamiz:
WITH nom AS (
-- bu yerda biror SELECT so'rovi
)
SELECT ... FROM nom;Diqqat qiling: WITH bloki o'zicha natija chiqarmaydi. U faqat vaqtinchalik jadvalni tayyorlab beradi. Asl natijani esa undan keyingi asosiy SELECT chiqaradi.
Aytaylik, biz Elektronika kategoriyasidagi mahsulotlar bilan ishlamoqchimiz. Avval shu mahsulotlardan vaqtinchalik elektronika jadvalini tuzamiz, so'ng undan nomlarni olamiz:
WITH elektronika AS (
SELECT * FROM mahsulotlar WHERE kategoriya = 'Elektronika'
)
SELECT nomi FROM elektronika ORDER BY nomi;Bu so'rov ikki bosqichda ishlaydi:
mahsulotlar dan faqat Elektronika qatorlarini olib, ularni elektronika nomli vaqtinchalik jadvalga joylaydi (Telefon, Noutbuk, Quloqchin).elektronika dan o'qiydi.Natija:
Noutbuk
Quloqchin
TelefonEslatma:
elektronika— bu haqiqiy jadval emas, faqat shu so'rov ichida yashaydigan vaqtinchalik nom. Boshqa so'rovda uni ishlatib bo'lmaydi.
CTE ichiga istalgan SELECT so'rovini yozish mumkin — shu jumladan WHERE sharti bilan. Masalan, narxi 1 000 000 dan qimmat mahsulotlardan vaqtinchalik jadval tuzaylik, so'ng undan nomlarni alifbo tartibida chiqaraylik:
WITH qimmatbaho AS (
SELECT * FROM mahsulotlar WHERE narx > 1000000
)
SELECT nomi FROM qimmatbaho ORDER BY nomi;Bu yerda qimmatbaho jadvaliga faqat ikkita mahsulot tushadi — Telefon va Noutbuk. Asosiy so'rov esa ularni nomi bo'yicha tartiblaydi:
Noutbuk
TelefonE'tibor bering: bir xil natijani oddiy SELECT nomi FROM mahsulotlar WHERE narx > 1000000 ORDER BY nomi bilan ham olsa bo'lardi. Lekin CTE so'rovni ikki aniq bosqichga bo'lib beradi: avval "qaysi qatorlarni olamiz", keyin "ulardan nimani chiqaramiz". So'rov murakkablashgani sari bu ajratish o'qishni ancha osonlashtiradi.
Muhim: CTE ichidagi so'rov bir nechta qator qaytarsa ham, tartibi kafolatlanmaydi. Tartibni asosiy so'rovda
ORDER BYbilan belgilang — biz yuqorida xuddi shunday qildik.
qimmatbaho yoki elektronika kabi nom so'rov nima qilayotganini darrov tushuntiradi.WITH faqat shu bitta so'rov uchun ishlaydi.Pastdagi kod oynasida mahsulotlar jadvali allaqachon yaratilgan va to'ldirilgan. Sizning vazifangiz — WITH (CTE) yordamida narxi 500000 dan qimmat mahsulotlardan iborat vaqtinchalik jadval tuzish va undan mahsulotlarning nomlarini alifbo tartibida chiqarish.