Soru
Kanat Havayolları operasyon merkezi her sabah bir pano açıyor: Dün kaç uçuş planlandı, kaçı iptal edildi, zamanında kalkış oranı ne, son yedi günün eğilimi ne, rötarların başlıca nedeni neydi? Bu soruların her biri farklı bir grain düzeyinde hesaplanır ve sonunda gün düzeyinde birleşir.
Sorgu
Büyük sorgu nasıl okunur?Yukarıdan aşağı, her CTE'yi ayrı bir tablo gibi düşün. Bir adımı anlamadıysan o CTE'nin adını en sondaki SELECT'e yazıp yalnızca onu çalıştır:
SELECT * FROM adim_adi LIMIT 20;WITH ucus AS ( -- 1) Uçuş düzeyi: gün, gecikme, iptal bayrağı
SELECT f.flight_id, date(f.sched_dep) AS gun, f.status,
ROUND((julianday(f.actual_dep) - julianday(f.sched_dep)) * 1440) AS gecikme
FROM hv_flights f
WHERE f.sched_dep >= '2024-12-01' AND f.sched_dep < '2025-01-01'
),
gunluk AS ( -- 2) Gün düzeyi: planlanan, iptal, zamanında kalkan
SELECT gun,
COUNT(*) AS planlanan,
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) AS iptal,
SUM(CASE WHEN gecikme <= 15 THEN 1 ELSE 0 END) AS zamaninda,
COUNT(gecikme) AS kalkan
FROM ucus
GROUP BY gun
),
neden AS ( -- 3) Her günün rötar nedenleri ve dakikaları
SELECT u.gun, d.reason, SUM(d.minutes) AS dakika
FROM hv_delays d
JOIN ucus u ON u.flight_id = d.flight_id
GROUP BY u.gun, d.reason
),
baslica AS ( -- 4) Günün en çok dakika getiren nedeni (eşitlikte alfabetik)
SELECT gun, reason, dakika,
ROW_NUMBER() OVER (PARTITION BY gun ORDER BY dakika DESC, reason) AS sira
FROM neden
)
SELECT g.gun, -- 5) Pano: günlük değerler + 7 günlük hareketli zamanında kalkış
g.planlanan, g.iptal,
ROUND(100.0 * g.zamaninda / g.kalkan, 1) AS otp,
ROUND(100.0 * SUM(g.zamaninda) OVER w / SUM(g.kalkan) OVER w, 1) AS otp_7gun,
b.reason AS baslica_neden,
b.dakika AS neden_dk
FROM gunluk g
LEFT JOIN baslica b ON b.gun = g.gun AND b.sira = 1
WINDOW w AS (ORDER BY g.gun ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)
ORDER BY g.gun;
Adım adım
| Adım | Ne yapar? | Çıktının bir satırı |
|---|---|---|
ucus | Aralık uçuşları; gün, durum ve kalkış gecikmesi | 2341, 2024-12-05, landed, 22 |
gunluk | Gün düzeyi sayımlar; kalkan = gecikmesi bilinen uçuş | 2024-12-05, 27, 1, 15, 26 |
neden | Gün × neden düzeyinde rötar dakikası | 2024-12-05, hava, 180 |
baslica | Her gün için nedenleri dakikaya göre sıralar | hava, 180, sıra 1 |
son SELECT | Günlük satıra en başlıca nedeni LEFT JOIN ile ekler; hareketli oran WINDOW ile | 2024-12-05, 27, 1, 57.7, 61.2, hava, 180 |
İki önemli ayrıntı
- Hareketli oran: 7 günün oranlarının ortalaması değil, 7 günün toplam zamanında kalkışının toplam kalkışa oranıdır:
SUM(zamaninda) OVER w / SUM(kalkan) OVER w. - Adlandırılmış pencere:
WINDOW w AS (...)aynı çerçeveyi iki kez yazmaktan kurtarır. SQL Server 2022 öncesi ve bazı SQL türleri desteklemez; o durumda çerçeve her OVER içinde tekrarlanır.
Neden LEFT JOIN?Hiç rötar yaşanmayan bir günde
baslica satırı yoktur. INNER JOIN o günü panodan düşürür; LEFT JOIN günü korur ve nedeni boş bırakır.