Bosh sahifa Wiki Common Table Expression

Common Table Expression

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