Common Table Expression (CTE) — bitta SQL statement boshida WITH bandi orqali nomlanadigan vaqtinchalik query natijasi. U murakkab so‘rovni mantiqiy qismlarga ajratish, bir natijaga qayta murojaat qilish va recursive iyerarxiyani yurish uchun ishlatiladi.
Oddiy CTE
WITH paid_orders AS (
SELECT customer_id, total
FROM orders
WHERE status = 'paid'
), customer_totals AS (
SELECT customer_id, SUM(total) AS amount
FROM paid_orders
GROUP BY customer_id
)
SELECT customer_id, amount
FROM customer_totals
WHERE amount >= 1000000;
CTElar yozilish tartibida keyingi CTE yoki asosiy queryga source bo‘ladi. Ularning scope’i faqat shu statement bilan cheklanadi; keyingi alohida queryda mavjud emas. Ustun nomlari ichki aliaslardan yoki CTE nomidan keyingi ro‘yxatdan olinadi.
Optimizer xulqi
CTE “natija albatta bir marta hisoblanib saqlanadi” degani emas. Ba’zi database versiyalarida u optimization fence bo‘lgan, boshqalarida optimizer uni tashqi queryga inline qiladi. PostgreSQL kabi tizimlarda materializationni boshqarish uchun mahsulotga xos kalit so‘zlar mavjud.
Inline qilish tashqi filterlarni ichkariga surib, keraksiz satrlarni erta kamaytiradi. Materialization qimmat hisobni bir marta bajarib ko‘p murojaatda foyda berishi mumkin, lekin katta temporary natija yaratadi. Query plan real qarorni ko‘rsatadi; faqat sintaksisga qarab performance xulosasi qilinmaydi.
Recursive CTE
Recursive CTE anchor va recursive memberdan tuziladi. Anchor boshlang‘ich satrlarni, recursive qism oldingi iteratsiya natijasidan keyingi satrlarni topadi:
WITH RECURSIVE org AS (
SELECT id, manager_id, name, 0 AS depth
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.manager_id, e.name, o.depth + 1
FROM employees e
JOIN org o ON e.manager_id = o.id
)
SELECT * FROM org;
Bu adjacency listdagi barcha avlodlarni yuradi. UNION ALL odatda tezroq, UNION esa ko‘rilgan qatorlarni deduplicate qilib ayrim sikllarni to‘xtatishi mumkin, lekin barcha cycle modelini hal qilmaydi.
Cycle va chuqurlik
Noto‘g‘ri parent bog‘lanishi cycle yaratib, recursive queryni juda uzoq ishlatishi mumkin. Path ustunida tashrif buyurilgan IDlarni saqlash, mahsulotning CYCLE imkoniyati yoki maksimal depth himoyasi qo‘llanadi. Faqat global recursion limitga tayanish xatoni aniqlamay, natijani kesib qo‘yishi mumkin.
Iyerarxiyada bitta node bir nechta parentga ega bo‘lsa natija daraxt emas, graph bo‘ladi va bir node turli path orqali takrorlanadi. Query biznes modeliga mos traversal va duplicate siyosatini belgilaydi.
O‘qiluvchanlik va cheklov
CTE nomlari filtered, ranked, totals kabi ma’noni ifodalasa query bosqichlari aniq ko‘rinadi. Juda ko‘p CTE esa data oqimini kuzatishni qiyinlashtiradi. Har bosqich output donadorligi va kaliti bilan hujjatlashtiriladi.
CTE access control chegarasi emas; undan olingan ustunlar foydalanuvchi ruxsatini avtomatik cheklamaydi. Katta DML statementlarda lock va transaction xulqi ham asosiy buyruqqa bog‘liq. Performance productionga o‘xshash data hamda actual query plan bilan tekshiriladi.
O‘zgartiruvchi CTE
PostgreSQL kabi ayrim tizimlar WITH ichida INSERT, UPDATE yoki DELETE va RETURNING natijasidan foydalanishga ruxsat beradi. Bu bir statement ichida o‘zgargan qatorlarni keyingi amal bilan bog‘laydi. Execution va snapshot semantikasi oddiy bosqichma-bosqich procedural kodga teng deb taxmin qilinmaydi. Bir qatordan bir necha marta o‘zgartirish noaniq natija berishi mumkin. Bunday querylar kichik transaction testi, constraint va aniq affected-row nazorati bilan qo‘llanadi.
Bog‘liq tushunchalar
WITH clause, Recursive query, Derived table, UNION ALL, Hierarchy, Cycle detection, Materialization, Query optimizer