2016-05-05 15 views
0

Ich habe diese Abfrage: (Entschuldigung für die Komplexität, ich bin nicht sicher, was ich ohne Auswirkungen auf die Frage entfernen)Probleme mit duplizierten Ids in aggregierten Unterabfrage

SELECT COUNT(*) AS total, 
SUM(o.total) AS total_loss, 
SUM((SELECT SUM(cost_price) FROM `orders_items` WHERE orders_id = o.orders_id)) AS cost_total , 
SUM((SELECT COUNT(*) FROM refunds AS r1 WHERE r1.order_id = r.order_id AND NOT r.reason IS NULL)) AS refund_count , 
SUM((SELECT COUNT(*) FROM exchanges AS e1 WHERE e1.order_id = e.order_id AND e.type = :countResend AND NOT e.reason IS NULL)) AS resend_count , 
SUM((SELECT COUNT(*) FROM exchanges AS e2 WHERE e2.order_id = e.order_id AND e.type = :countExchange AND NOT e.reason IS NULL)) AS exchange_count 
FROM orders AS o 
JOIN sales_channel_config AS s ON o.sales_channel = s.sales_channel AND o.sub_sales_channel = s.sub_sales_channel 
JOIN courier_service AS cs ON o.courier_service = cs.code 
LEFT JOIN refunds AS r ON o.orders_id = r.order_id 
JOIN orders_items AS oi ON o.orders_id = oi.orders_id 
JOIN third_party_config AS tc ON SUBSTRING(oi.product_id_new, 3, 2) = tc.code 
LEFT JOIN exchanges AS e ON o.orders_id = e.order_id 
WHERE 1 = 1 
AND o.tracking_num NOT IN (:cancelStatus) 
AND (o.order_date >= :startDate AND o.order_date <= :endDate) 
AND o.courier_service = :courier 
AND SUBSTRING(oi.product_id_new, 3, 2) = :supplier 
AND (NOT r.reason IS NULL OR NOT e.reason IS NULL) 

Das Problem, das ich habe, ist, dass die verschiedene SUM((query)) Klauseln zählen doppelte Aufträge, die sich als schwierig zu lösen erweist. Zum Beispiel:

SUM((SELECT COUNT(DISTINCT r1.order_id) FROM refunds AS r1 WHERE r1.order_id = r.order_id AND NOT r.reason IS NULL)) AS refund_count , 

Und

SUM((SELECT COUNT(*) FROM refunds AS r1 WHERE r1.order_id = r.order_id AND NOT r.reason IS NULL GROUP BY r1.order_id)) AS refund_count , 

Sie die resultierenden SUM gar nicht senken. Ich habe bestätigt, dass die zurückgegebenen Daten Duplikate über eine andere strukturell identische Abfrage enthalten, die Zeilen von der übergeordneten Abfrage zurückgibt. Wenn die andere Abfrage ohne doppelte Filterung ausgeführt wird, stimmen die Zählwerte korrekt überein, sodass ich davon überzeugt bin, dass meine Problemabfrage korrekt ist, abgesehen von der Aufnahme duplizierter Auftrags-IDs.

Kann also jemand einen anderen Ansatz vorschlagen, den ich ausprobieren könnte?

+0

Was ist die Summe, die Sie bekommen? Ist es nicht immer 1? Wo ist die äußere Abfragegruppe nach Klausel? – sagi

+0

@sagi Die Gruppierung der äußeren Abfrage gibt die Gesamtsummen pro Auftrag zurück, also die Anzahl der Wiederholungen. Die Summenergebnisse, die ich mit meinen aktuellen Parametern erhalte, sind: exchange_count: 2, refund_count: 41 und resend_count: 3, was genau ist, bis auf duplizierte Bestellungen. –

Antwort

0

Für alle, die davon profitieren könnten:

ich die meisten der Auswahllogik entfernt und auf orders_id gruppiert, die mir eine ganz genaue Liste der relevanten Befehle gibt:

SELECT o.orders_id AS order_id, r.id AS refund_id, e.id AS exchange_id, e.type AS exchange_type 
FROM orders AS o 
JOIN sales_channel_config AS s ON o.sales_channel = s.sales_channel AND o.sub_sales_channel = s.sub_sales_channel 
JOIN courier_service AS cs ON o.courier_service = cs.code 
LEFT JOIN refunds AS r ON o.orders_id = r.order_id 
JOIN orders_items AS oi ON o.orders_id = oi.orders_id 
JOIN third_party_config AS tc ON SUBSTRING(oi.product_id_new, 3, 2) = tc.code 
LEFT JOIN exchanges AS e ON o.orders_id = e.order_id 
WHERE 1 = 1 
AND o.tracking_num NOT IN (:cancelStatus) 
AND (o.order_date >= :startDate 
AND o.order_date <= :endDate) 
AND o.courier_service = :courier 
AND SUBSTRING(oi.product_id_new, 3, 2) = :supplier 
AND (NOT r.reason IS NULL OR NOT e.reason IS NULL) 
GROUP BY (o.orders_id) 

ich die Kugel gebissen haben Hier. Ich werde einige Nachbearbeitungen machen, um die Zählungen selbst zu bekommen, was zumindest für mich jetzt möglich ist.

Immer noch nicht verstehen, warum unterschiedliche Werte in den Subselects obwohl fehlgeschlagen.