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.
- Aynı gün birden çok işlem varsa tek gün sayılır mı? (Evet olmalı: önce gün düzeyine tekilleştir.)
- Tüm işlem türleri mi (faiz tahakkuku gibi otomatik olanlar dahil)?
- Seri takvim günüyle mi, iş günüyle mi ölçülüyor?
Yaklaşım
- Hesap × gün düzeyine indir (DISTINCT, zaman damgasını date() ile güne çevir).
- Her hesapta günleri sırala ve ROW_NUMBER ver.
- Gün numarası − sıra numarası, aynı serideki her gün için sabit kalır: bu değer seri anahtarıdır.
- 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ı
| Durum | Ne olur? |
|---|---|
| Aynı gün iki işlem | DISTINCT olmazsa ROW_NUMBER iki kez artar, seri kırılmış görünür |
| Tek günlük seri | Seri uzunluğu 1; HAVING ile elenir |
| Ay ve yıl geçişi | Tarihi 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ı
- Bir günlük boşluğa izin verilseydi (31 Ocak ve 2 Şubat aynı seri)?
- Her hesabın yalnızca en uzun serisi nasıl alınır? (ROW_NUMBER ile ikinci kez sırala)
- Milyonlarca satırda hangi indeks gerekir? (account_id, txn_time)
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.