Testler “sıfır satır” döndürmeli
dbt ve benzeri araçlardaki yaygın yaklaşım: Her test, sorunlu satırları döndüren bir sorgudur. Sonuç boşsa test geçer.
-- 1) Benzersizlik: order_id tekrar ediyor mu? SELECT order_id, COUNT(*) FROM orders GROUP BY order_id HAVING COUNT(*) > 1;
-- 2) Referans bütünlüğü: var olmayan ürüne ait sipariş satırı var mı? SELECT oi.* FROM order_items oi LEFT JOIN products p ON p.product_id = oi.product_id WHERE p.product_id IS NULL;
-- 3) Kabul edilen değerler
SELECT DISTINCT status FROM orders
WHERE status NOT IN ('delivered', 'shipped', 'cancelled', 'returned');
-- 4) Aralık / mantık kontrolleri SELECT * FROM order_items WHERE quantity <= 0 OR discount < 0 OR discount >= 1; SELECT * FROM products WHERE cost > price;
Tek sorguda kalite özeti
SELECT 'customers.email NULL' AS test, COUNT(*) AS hatali FROM customers WHERE email IS NULL UNION ALL SELECT 'customers.city NULL', COUNT(*) FROM customers WHERE city IS NULL UNION ALL SELECT 'orders sipariş tarihi < kayıt tarihi', COUNT(*) FROM orders o JOIN customers c ON c.customer_id = o.customer_id WHERE o.order_date < c.signup_date;
Derinleş: veri kalitesinin beş boyutu
“Veri kötü” demek eyleme dönüşmez. Kaliteyi ölçülebilir boyutlara ayırınca her sorun için bir test, bir sahip ve bir eşik tanımlanabilir:
| Boyut | Soru | Örnek test |
|---|---|---|
| Tamlık | Olması gereken değer var mı? | Müşterinin ilçesi boş mu? |
| Tekillik | Her varlık bir kez mi? | Aynı order_id iki kez geçiyor mu? |
| Geçerlilik | Değer izin verilen aralıkta / biçimde mi? | Puan 1–5 dışında mı? |
| Tutarlılık | İlişkili kayıtlar birbiriyle çelişiyor mu? | Sipariş, müşterinin kayıt tarihinden önce mi? |
| Güncellik | Veri beklenen tazelikte mi? | Son kayıt kaç gün önce geldi? |
Bunlara bazen doğruluk (değer gerçeği yansıtıyor mu) da eklenir; ama doğruluk genelde dış bir kaynakla karşılaştırma gerektirir ve tek başına SQL ile ölçülemez.
Lezzet Kurye kalite karnesi
SELECT 'tamlık' AS boyut, 'lk_customers.district boş' AS test, COUNT(*) AS hatali
FROM lk_customers WHERE district IS NULL
UNION ALL
SELECT 'tekillik', 'lk_orders.order_id tekrarı', COUNT(*)
FROM (SELECT order_id FROM lk_orders GROUP BY order_id HAVING COUNT(*) > 1) t
UNION ALL
SELECT 'geçerlilik', 'puan 1-5 dışında', COUNT(*)
FROM lk_ratings WHERE food_score NOT BETWEEN 1 AND 5 OR courier_score NOT BETWEEN 1 AND 5
UNION ALL
SELECT 'tutarlılık', 'sipariş, müşteri kaydından önce', COUNT(*)
FROM lk_orders o JOIN lk_customers c ON c.customer_id = o.customer_id
WHERE substr(o.placed_at, 1, 10) < c.signup_date
UNION ALL
SELECT 'tutarlılık', 'davetli, davet edenden önce kayıtlı', COUNT(*)
FROM lk_customers c JOIN lk_customers d ON d.customer_id = c.referred_by
WHERE c.signup_date < d.signup_date
UNION ALL
SELECT 'güncellik', 'son siparişten bu yana gün (rapor günü 2025-01-03)',
julianday('2025-01-03') - julianday(MAX(date(placed_at)))
FROM lk_orders;
Karnede iki gerçek bulgu var: 1.209 müşterinin 74'ünde ilçe boş (tamlık %93,9) ve davetli 294 müşterinin 136'sı onu davet edenden önce kaydolmuş görünüyor. İkincisi tipik bir tutarlılık sorunudur: ya kayıt tarihi sonradan güncelleniyor ya da davet bilgisi başka bir akıştan geliyor. Kaynağı bilen ekiple konuşmadan “düzeltme”. Sipariş ile kayıt tarihi testi ise 0 döner: temiz çıkan test de bilgidir, her yükte yine çalışmalıdır.
severity: warn / error ve warn_if, error_if ayarları bunu sağlar.Sık hata: testleri yalnızca yeni tabloya yazmak. En değerli testler, kaynaklar arasındaki ilişkileri (sipariş–müşteri, değerlendirme–sipariş) kontrol eden tutarlılık testleridir; çünkü tek tabloya bakan testler bu çelişkileri hiç görmez.