2012-04-10 7 views
0

Die einfache Arbeits Abfrage, listen die Anzahl der Lizenzen für jeden Lizenztyp:Warum erhalte ich falsche SUMME in meiner MYSQL-Abfrage, die zwei Tabellen verbindet?

Abfrage:

SELECT 
    COUNT(licenses.licenseID) AS total 
FROM 
    licenses 
GROUP BY 
    licenses.licensetypeID 

Ergebnisse:

total 
===== 
389 
14 
    2 
    5 
    3 
    1 
    1 

Jetzt möchte ich den Gewinn aus den Lizenzen zusammenzufassen . Eine Tabelle transactions enthält alle Transaktionen von PayPal. Ich benutze mc_gross um zusammenzufassen. Manchmal gibt es Rückerstattungen, also mc_gross ist negativ und es gibt mehr Transaktionen als Lizenzen.

In meiner aktuellen Datenbank wurden vier Lizenzen entfernt, da die Transaktion zurückerstattet wurde.

Mein Versuch:

SELECT 
    COUNT(licenses.licenseID) AS total, 
    SUM(transactions.mc_gross) AS gross 
FROM 
    licenses 
    LEFT JOIN transactions ON licenses.txn_id = transactions.txn_id 
GROUP BY 
    licenses.licensetypeID 

Das Ergebnis:

393  9020.00 
14  NULL 
    2  NULL 
    5  NULL 
    3  100.00 
    1  NULL 
    1  NULL 

Beachten Sie, dass der erste Lizenztyp nun insgesamt vier mehr als die erste Abfrage. Daraus schließe ich, dass es die zusätzlichen Zeilen in der Transaktionstabelle hochzählt. Aber ich verstehe nicht, warum, weil ich dachte, ein LEFT JOIN würde alle Zeilen für die linke Tabelle licenses nehmen und mit dem verfügbaren transactions verbinden.

Wenn ich mir die verschiedenen Verbindungen ansehe, kann ich keinen Sinn daraus ziehen, um mein gewünschtes Ergebnis zu erzielen.

Mache ich eine falsche Verbindung? Oder gruppiere ich nach dem falschen Wert?

Beachten Sie, dass ich alle Lizenztypen auflisten möchte - auch wenn sie zu null zählen.

(Lassen Sie mich wissen, wenn die ganze Tabellenstruktur erforderlich ist - ich habe es übersprungen die Frage zu lange zu vermeiden, dass ich hoffe, dass alle relevanten Informationen enthalten..)

+0

try count (distinct license.licenseid) um das Zählen von Duplidaten zu vermeiden – Jason

+0

@Jason: Das hat meine Zählung korrigiert. Aber jetzt sehe ich ein anderes Problem. Der Gesamtgewinn ist auch falsch.Aber das liegt daran, was @StilesCrisis erwähnt, es gibt einige Male 'txn_id', weil die Zahlung aussteht. Sieht so aus, als müsste ich diese herausfiltern. – thomthom

Antwort

2

Es gibt wahrscheinlich mehrere Transaktionen mit der gleichen TXN_ID . In diesem Fall wird ein Join die gleiche Lizenz einmal für jede passende Transaktion aufführen.

+0

Ah, ja. Blick auf die Daten. Manchmal wird eine Transaktion aufgezeichnet, die Verarbeitung steht jedoch aus. In diesen Fällen wird eine zweite Transaktion mit derselben 'txn_id' auftreten. Das ist es, was es ablegt. – thomthom

0

Wenn Erstattungen in der Transaktionstabelle als negative Beträge eingegeben werden, sollten Sie die ursprüngliche Transaktion nicht entfernen. Beide müssen vorhanden sein, um das Gesamtguthaben auf 0 zu setzen. Da Sie 4 weitere Transaktionen sehen, als Sie dachten, und Sie wissen, dass es 4 Rückerstattungen gab, würde ich sagen, dass sowohl die ursprüngliche Transaktion als auch die Rückerstattungstransaktion in der Transaktionstabelle sind so wie sie sein sollten.

+0

Sie haben Recht, es ist nicht meine Rückerstattung. Es handelt sich um doppelte 'txn_id'-Einträge aufgrund gelegentlicher ausstehender Zahlungen, die doppelte Transaktionseinträge mit der gleichen 'txn_id' verursachen. Ich habe das jetzt anhand des Kommentars von @StilesCrisis gesehen. – thomthom

+0

Wenn ich richtig liege, aber Sie echte Duplikate haben und nicht einfach mehrere Transaktionen pro Lizenz, wenn Sie zurückerstattet werden, dann wäre Ihre nicht eindeutige Anzahl größer als (Anzahl der Lizenzen + Anzahl der Erstattungen). – Simon

0

Dank der Kommentare Ich habe mir gelungen, eine Abfrage zu erstellen, die eine korrekte Ergebnisse liefert:

SELECT 
    COUNT(distinct licenses.licenseID) AS total, 
    SUM(temp.mc_gross/temp.quantity) AS gross 
FROM 
    licenses 
    LEFT JOIN 
    (SELECT txn_id, mc_gross, quantity 
     FROM transactions 
     WHERE valid = 'VERIFIED-PAID' 
    ) AS temp ON licenses.txn_id = temp.txn_id 
GROUP BY 
    licenses.licensetypeID 

Korrekte Daten:

total gross 
=================== 
389  7780.000000 
14  NULL 
    2  NULL 
    5  NULL 
    3  60.000000 
    1  NULL 
    1  NULL 

UPDATE - Verbesserte Abfrage:

SELECT 
    COUNT(licenses.licenseID) AS total, 
    SUM(transactions.mc_gross/transactions.quantity) AS gross 
FROM 
    licenses 
    LEFT JOIN transactions ON licenses.txn_id = transactions.txn_id AND transactions.valid = 'VERIFIED-PAID' 
GROUP BY 
    licenses.licensetypeID 
+1

Sie hätten die 'valid = 'VERIFIED-PAID'-Prüfung in der' ON'-Klausel Ihres' JOIN's durchführen können, denke ich. – StilesCrisis

+0

@StilesCrisis: Ja! Es tut! Ich wusste nicht, dass du das kannst. Viel einfacher und viel einfacher zu lesen. Vielen Dank! – thomthom

Verwandte Themen