Sorun: şişen toplamlar
Müşteri tablosunu siparişlerle, siparişleri satırlarla birleştirdiğinde her müşteri, sipariş satırı kadar tekrar eder. Bu satırlarda müşteri düzeyindeki bir değeri (ör. sipariş sayısı) toplarsan sonuç şişer.
-- YANLIŞ: sipariş sayısı satır sayısı kadar şişiyor SELECT c.segment, COUNT(o.order_id) AS siparis FROM customers c JOIN orders o ON o.customer_id = c.customer_id JOIN order_items oi ON oi.order_id = o.order_id GROUP BY c.segment;
-- DOĞRU 1: tekrarsız say SELECT c.segment, COUNT(DISTINCT o.order_id) AS siparis FROM customers c JOIN orders o ON o.customer_id = c.customer_id JOIN order_items oi ON oi.order_id = o.order_id GROUP BY c.segment;
Önce özetle, sonra birleştir
İki farklı ayrıntı düzeyindeki ölçüyü (sipariş sayısı ve ciro) birlikte istiyorsan her birini kendi düzeyinde özetleyip sonra birleştir:
WITH s AS ( -- müşteri başına sipariş sayısı SELECT customer_id, COUNT(*) AS siparis FROM orders GROUP BY customer_id ), c AS ( -- müşteri başına net ciro SELECT o.customer_id, SUM(oi.quantity * oi.unit_price * (1 - oi.discount)) AS ciro FROM orders o JOIN order_items oi ON oi.order_id = o.order_id WHERE o.status = 'delivered' GROUP BY o.customer_id ) SELECT s.customer_id, s.siparis, ROUND(c.ciro, 0) AS ciro FROM s JOIN c ON c.customer_id = s.customer_id ORDER BY ciro DESC LIMIT 5;
SağlamaBirleştirmeden önce ve sonra satır sayısını ve bir toplamı karşılaştır. Tutmuyorsa bir yerde çoğalma vardır.
Ayrıntı düzeyi (grain)
Her tablonun bir satırı neyi temsil eder? orders: bir sipariş; order_items: bir sipariş satırı. Sorgunun sonucundaki bir satırın neyi temsil edeceğini önceden söylemek, çoğalma hatalarının çoğunu önler.