Ana içeriğe geç
Kesit SQL
İleri · Mülakat Hazırlığı

Mülakat kalıbı: ardışık günler, seriler ve “en az 3 gün üst üste”

Boşluklar ve adalar sorusunun iki çözümü: tarih − ROW_NUMBER ve LAG ile işaretle-topla.

Uygulamada aç, 5 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

Soru

Görüşmeci“Ilgaz Bank'ta en az 3 gün üst üste işlem yapılmış hesapları bul.” Takip: “Her hesabın en uzun ardışık serisi kaç gün?”

Önce netleştir

Kod yazmadan önce sorulacak sorular. Her biri farklı bir sorguya götürür; sormamak en sık puan kaybıdır.

Yaklaşım

  1. Hesap × gün düzeyine indir (DISTINCT, zaman damgasını date() ile güne çevir).
  2. Her hesapta günleri sırala ve ROW_NUMBER ver.
  3. Gün numarası − sıra numarası, aynı serideki her gün için sabit kalır: bu değer seri anahtarıdır.
  4. Hesap × seri anahtarına göre grupla, uzunluğu say, filtrele.

Çözüm 1: tarih − ROW_NUMBER

WITH g AS (
  SELECT DISTINCT account_id, date(txn_time) AS gun
  FROM bank_txns
),
n AS (
  SELECT account_id, gun,
         julianday(gun) - julianday('2000-01-01')
           - ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY gun) AS seri
  FROM g
)
SELECT account_id, MIN(gun) AS baslangic, MAX(gun) AS bitis, COUNT(*) AS gun_sayisi
FROM n
GROUP BY account_id, seri
HAVING COUNT(*) >= 3
ORDER BY gun_sayisi DESC, account_id
LIMIT 10;

Çözüm 2: LAG ile işaretle ve kümülatif topla

WITH g AS (
  SELECT DISTINCT account_id, date(txn_time) AS gun FROM bank_txns
),
i AS (
  SELECT account_id, gun,
         CASE WHEN julianday(gun) - julianday(LAG(gun) OVER (PARTITION BY account_id ORDER BY gun)) = 1
              THEN 0 ELSE 1 END AS yeni
  FROM g
),
s AS (
  SELECT account_id, gun,
         SUM(yeni) OVER (PARTITION BY account_id ORDER BY gun ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS seri
  FROM i
)
SELECT account_id, COUNT(*) AS gun_sayisi
FROM s
GROUP BY account_id, seri
HAVING COUNT(*) >= 3
ORDER BY gun_sayisi DESC, account_id
LIMIT 10;

İki çözüm aynı sonucu verir. Birincisi daha kısadır; ikincisi “1 günlük boşluğu tolere et” ya da “30 dakikadan uzun ara yeni oturum başlatır” gibi eşik içeren varyasyonlara daha kolay uyarlanır. Görüşmeci genellikle ikinci varyasyonu takip sorusu olarak sorar.

Sınır durumları

DurumNe olur?
Aynı gün iki işlemDISTINCT olmazsa ROW_NUMBER iki kez artar, seri kırılmış görünür
Tek günlük seriSeri uzunluğu 1; HAVING ile elenir
Ay ve yıl geçişiTarihi gün numarasına çevirmek ay sonlarını doğru ele alır
Saatli zaman damgasıÖnce güne indir; yoksa aynı gün farklı satırlar olur

Takip soruları

Görüşmeci neye bakıyor?Önce gün düzeyine tekilleştirmeyi kendiliğinden yapman ve “tarih eksi sıra numarası neden sabit kalır?” sorusunu açıklayabilmen.
Alıştırmalara geç (5)