SQL JOIN, GROUP BY auf drei Tische zu bekommen Summen
Habe ich geerbt den folgenden DB-design. Tabellen sind:
customers
---------
customerid
customernumber
invoices
--------
invoiceid
amount
invoicepayments
---------------
invoicepaymentid
invoiceid
paymentid
payments
--------
paymentid
customerid
amount
Meine Abfrage zurückgeben muss, invoiceid, ist der Rechnungsbetrag (in der Tabelle "Rechnungen"), und der fällige Betrag (Rechnungsbetrag abzüglich der Zahlungen, die gemacht worden sind in Richtung auf die Rechnung) für einen bestimmten customernumber. Ein Kunde kann mehrere Rechnungen.
Die folgende Abfrage gibt mir die doppelte Datensätze, wenn mehrere Zahlungen auf eine Rechnung:
SELECT i.invoiceid, i.amount, i.amount - p.amount AS amountdue
FROM invoices i
LEFT JOIN invoicepayments ip ON i.invoiceid = ip.invoiceid
LEFT JOIN payments p ON ip.paymentid = p.paymentid
LEFT JOIN customers c ON p.customerid = c.customerid
WHERE c.customernumber = '100'
Wie kann ich dieses Problem lösen?
- wie viele Zahlungen auf Rechnung Zeilen existieren können, die für eine Rechnung? wie viele Zahlungen vorhanden sein können, für jeden paymentid?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin nicht sicher, ob ich Sie, aber das könnte sein was du suchst:
Dies würde zu erhalten, Ihnen die Beträge Beträge in Fall gibt es mehrere payment-Zeilen für jede Rechnung
amount
Spalten incoalesce
oderisnull
; mit MS-SQL, eventuell vorhandene NULL-Werte, z.B. aus derleft join
s führt dazu, dass die ganze Sache zu bewerten, zu NULL. Ich weiß, dass einige SQL-Dialekte erlauben NULL == 0, aber das führt zu einem religiösen Krieg, so ...Vielen Dank für die Antworten!
Saggi " Maleachi, dass die Abfrage leider Summen der Rechnungsbetrag in Fällen, in denen es mehr als eine Zahlung. Sagen, es gibt zwei Zahlungen auf ein $39 Rechnung von $18 und $12. Anstatt also zu Ende mit einem Ergebnis, das aussieht wie:
Werden Sie am Ende mit:
Charles Bretana, im Kurs zu trimmen meine Anfrage nach unten, um die einfachste mögliche Abfrage, die ich (dummerweise) entfällt eine zusätzliche Tabelle, customerinvoices, die eine Verbindung zwischen Kunden und Rechnungen. Dies kann verwendet werden, um zu sehen, Rechnungen für die Zahlungen noch nicht gemacht.
Nach viel zu kämpfen, ich denke, dass die folgende Abfrage gibt, was ich brauche es zu:
Würde Euch einig?
Erstens, müsste es nicht eine CustomerId in der Tabelle "Rechnungen"? Wie es ist, Sie können nicht führen Sie diese Abfrage für Rechnungen, die keine Zahlungen auf Sie noch. Wenn es keine Zahlungen auf eine Rechnung, diese Rechnung wird nicht einmal zeigen, bis in den Ausgang der Abfrage, auch wenn Sie einen outer-join...
Auch, Wenn ein Kunde eine Zahlung, wie Sie wissen, welche Rechnung es zu befestigen ? Wenn der einzige Weg ist durch die InvoiceId auf den stub, der kommt mit der Bezahlung, dann sind Sie (vielleicht unpassend) zuordnen Rechnungen mit den Kunden, der bezahlt Sie, statt mit den Kunden, die diese bestellt haben... . (Manchmal ist eine Rechnung kann bezahlt werden durch jemanden anderen als den Kunden, der die bestellten Dienste)
Habe ich einen Tipp für diejenigen, die wollen, Holen Sie verschiedene aggregierte Werte aus der gleichen Tabelle.
Können sagen, ich habe Tabelle mit Benutzer und die Tabelle mit Punkte, die der Benutzer erwerben. Also die Verbindung zwischen Ihnen ist 1:N (ein Nutzer, viele Punkte records).
Nun in der Tabelle 'Punkte' ich auch speichern die Informationen über für was haben die Benutzer bekommen die Punkte (login, Klick auf ein banner usw.). Und ich möchte, um eine Liste aller Benutzer bestellt
SUM(points)
UND dann durchSUM(points WHERE type = x)
. Das ist zu sagen, bestellt durch alle Punkte, die der Benutzer hat und dann durch die Punkte der Anwender für eine bestimmte Aktion (zB. login).SQL wäre:
Die Schönheit von diesem ist in der
SUM(points.points * (points.type = 7))
wo die innere Klammer wertet entweder mit 0 oder 1 so ist die Multiplikation der bestimmten Punkte-Wert von 0 oder 1, je nach wheteher es entspricht der Art der Punkte, die wir wollen.Ich weiß, das ist spät, aber es hat die Antwort auf Ihre ursprüngliche Frage.