2012-03-27 7 views
2

Dies ist meine SQL-Abfrage, die zwei Tabellen verknüpft:Wie aggregierte SUM-Funktion auf das Ergebnis von SUM in INNER JOIN zu verwenden?

SELECT `o`.`orderID`, 
     SUM(i.partialAmount) AS `amount` 
FROM `OrderTable` AS `o` 
     INNER JOIN `Item` AS `i` 
     ON i.orderID = o.orderID 
GROUP BY `o`.`orderID` 

Artikel auf Aufträge über 1-zu-viele-Beziehung verbunden sind. Jeder Artikel hat eine partialAmount-Spalte und ich addiere diese Teilbeträge, um einen Gesamtbetrag für jede Bestellung zu erhalten.

Ich möchte aber einen Gesamtbetrag für alle Bestellungen bekommen, wie geht das?

So würde Ich mag so etwas wie: SUM (Betrag) AS totalAmount aber das funktioniert nicht:

SELECT `o`.`orderID`, 
     SUM(i.partialAmount) AS `amount`, 
     SUM(amount) AS `totalAmount` 
FROM `OrderTable` AS `o` 
     INNER JOIN `Item` AS `i` 
     ON i.orderID = o.orderID 
GROUP BY `o`.`orderID` 

Ich will nicht mit ROLLUP verwenden - weil ich nicht eine zusätzliche Zeile wollen .

Erwarteter Ausgang:

----------------------------------------------------------------------- 
| orderID  |  amount  |   totalAmount   | 
----------------------------------------------------------------------- 
| 1    |   2   |    5    | 
----------------------------------------------------------------------- 
| 2    |   3   |    5    | 
----------------------------------------------------------------------- 
+1

hmmm ... was ist falsch mit Rollup? – ajreal

+0

Nicht sicher, dass Sie alle drei in einer Abfrage erhalten können. Die ersten zwei Spalten, die Sie auswählen, haben mehrere Zeilen mit mehreren unterschiedlichen Werten. Die dritte Spalte, die Sie auswählen, hat eine Zeile mit einem einzelnen Wert. Wie möchten Sie, dass diese Daten Ihnen präsentiert werden? Soll der gleiche Wert für die dritte Spalte in jeder Zeile wiederholt werden? – Travesty3

+1

@ Travestie3 Ja. –

Antwort

1

Wenn alles, was Sie wollen eine Gesamtlinie ist, können Sie so etwas wie dieser Code tun. Es gibt auch andere Ansätze als auch, je nachdem, wie wenn Sie die ausgewählten Aufträge filtern

SELECT `o`.`orderID`, 
     SUM(i.partialAmount) AS `amount` 
FROM `OrderTable` AS `o` 
     INNER JOIN `Item` AS `i` 
     ON i.orderID = o.orderID 
GROUP BY `o`.`orderID` 
UNION 
SELECT 999999,sum(i.partialAmount) as 'Amount' 
FROM Item i 
+0

Ja, das ist alles, woran ich denken kann, aber es könnte klüger sein, '-1' für die gefälschte orderID zu wählen.Auf diese Weise riskieren Sie keine Kollision mit einer tatsächlichen Bestellnummer '999999'. Müssen Sie den Spalten auch keine Aliase in der zweiten SELECT-Abfrage geben, damit die Spalten übereinstimmen? – Travesty3

+0

@Sparky Ich habe meine Frage mit einer erwarteten Ausgabe aktualisiert. –

1

Dies ist ein Hit auf Leistung sein wird (und geht davon aus, dass jede Zeile von Item einen Auftrag hat):

SELECT `o`.`orderID`, 
     SUM(i.partialAmount) AS `amount`, 
     (SELECT SUM(partialAmount) FROM `Item`) TotalAmount 
FROM `OrderTable` AS `o` 
     INNER JOIN `Item` AS `i` 
     ON i.orderID = o.orderID 
GROUP BY `o`.`orderID` 
0

Wenn Sie den Gesamtwert in jeder Zeile wollen Sie sum() über Funktion nutzen könnten, die Sie würde beide Summen http://msdn.microsoft.com/en-us/library/ms189461.aspx

für insgesamt

läuft
sum(amount) over() 

für Teilsumme

sum(amount) over (partition by o.orderid) 

wie diese

SELECT distinct `o`.`orderID`, 
     SUM(i.partialAmount) over (partition by orderid) AS `amount`, 
     SUM(i.partialAmount) over() AS `totalAmount` 
FROM `OrderTable` AS `o` 
     INNER JOIN `Item` AS `i` 
     ON i.orderID = o.orderID 
+0

Gibt es das Schlüsselwort "over" in MySQL? – Travesty3

+0

@ Travestie3 Es tut nicht ... Selbst wenn es tat, würde dies Duplikate zurückgeben, da es eine Reihe für jeden Gegenstand zurückgeben würde, nicht eine Reihe für jeden Auftrag. – GarethD

+0

Ich habe einen Unterschied hinzugefügt, der die Duplikate entfernen sollte – rlobban

1

aussehen würde ich sehr anstatt SQL tun, diese Art der Sache in der Anwendung raten würde, wie es repitition der Arbeit ist, aber es kann wie folgt erreicht werden:

SELECT OrderTable.OrderID, 
     SUM(PartialAmount) AS Amount, 
     TotalAmount 
FROM OrderTable, 
     Item, 
     (SELECT SUM(PartialAmount) AS TotalAmount FROM Item) AS total 
WHERE Item.OrderID = Ordertable.OrderID 
GROUP BY OrderTable.OrderID, TotalAmount 

Ich kann die Ausführung pla nicht überprüfen n, um dies mit der Option der Subselect zu vergleichen, die in einer anderen Antwort von Lamak veröffentlicht wurde, aber SQL Server optimiert das Kreuz definitiv besser als der Subselect.