2010-11-03 5 views
5

Ich arbeite an diesem SQL-Problem:SQL-Problem mit Aggregatfunktionen in Where-Klausel

Zeigen Sie alle Bestellungen, deren geladene Menge und tatsächliche Menge unterschiedlich sind. Zeigen Sie dies, indem Sie die Bestellnummer, den Bestellbetrag für jede Bestellung, den tatsächlichen Betrag (berechnet durch Hinzufügen der Preise aller Artikel in der Bestellung) und die Differenz zwischen den beiden anzeigen. Sortieren Sie die Ergebnisse, um zuerst die mit den größten Unterschieden anzuzeigen.

Ich erhalte den folgenden Code, wenn Sie die Anweisung unter SQL ausgeführt wird:

Fehlercode -1, SQL-Status 42903: Ungültige Verwendung einer Aggregatfunktion.

select 
    purchaseorder.ponum, 
    purchaseorder.amount, 
    sum(poitems.quantity*poitems.unitprice), 
    purchaseorder.amount-sum(poitems.quantity*poitems.unitprice) 
from purchaseorder, poitems 
where 
    purchaseorder.ponum = poitems.ponum 
    and purchaseorder.amount!=sum(poitems.quantity*poitems.unitprice) 
group by 
    purchaseorder.ponum, 
    purchaseorder.amount 

Ich denke, es ist, weil ich eine Aggregatfunktion in meiner WHERE-Klausel verwende.

Wie kann ich dieses Problem beheben ???

Danke,

Antwort

0

Hier ist, was für mich gearbeitet hat. Danke Leute!

+0

ist 'Menge' immer größer als' tatsächliche'? Sonst könnten Sie 'order by ABS (diff)' oder etwas Ähnliches abhängig von Ihrem SQL-Stil wünschen – tobyodavies

5

Try this:

select 
    purchaseorder.ponum, 
    purchaseorder.amount, 
    sum(poitems.quantity*poitems.unitprice), 
    purchaseorder.amount-sum(poitems.quantity*poitems.unitprice) 
from purchaseorder, poitems 
where 
    purchaseorder.ponum = poitems.ponum 
group by 
    purchaseorder.ponum, 
    purchaseorder.amount 
having 
    purchaseorder.amount!=sum(poitems.quantity*poitems.unitprice) 
+0

Das tut nicht die Reihenfolge, die er angefordert hat - mit dem höchsten Diff zuerst;) – tobyodavies

2

Sie können nicht ein Aggregat in einer where Klausel haben - das ist, was having ist - Änderung

select purchaseorder.ponum, 
     purchaseorder.amount, 
     sum(poitems.quantity*poitems.unitprice) as actual, 
     purchaseorder.amount - sum(poitems.quantity*poitems.unitprice) as diff 
from purchaseorder, 
     poitems 
where purchaseorder.ponum = poitems.ponum 
group by purchaseorder.ponum, 
     purchaseorder.diff 
having diff != 0 
order by ABS(diff) desc 
+0

Dank für das Sehen, dass ich es bestellt benötigen. Ich bekomme diesen Fehler bei der Verwendung Ihres Codes obwohl: – novicePrgrmr

+0

Fehlercode -1, SQL-Status 42X04: Spalte 'DIFF' ist entweder nicht in einer Tabelle in der FROM-Liste oder erscheint innerhalb einer Join-Spezifikation und ist außerhalb des Bereichs der Verknüpfung Spezifikation oder erscheint in einer HAVING-Klausel und ist nicht in der GROUP BY-Liste. Wenn dies eine CREATE- oder ALTER TABLE-Anweisung ist, ist "DIFF" keine Spalte in der Zieltabelle. – novicePrgrmr

+0

sehen, ob die Bearbeitung funktioniert (ich habe gerade getan, was der Fehler sagte, noch ungetestet: P) – tobyodavies

1

Es sieht aus wie Sie sollten stattdessen den HAVING-Klausel verwenden:

SELECT ... 
FROM  purchaseorder 
JOIN  poitems ON (purchaseorder.ponum = poitems.ponum) 
GROUP BY purchaseorder.ponum, purchaseorder.amount 
HAVING purchaseorder.amount != sum(poitems.quantity * poitems.unitprice); 

Die Klausel HAVING wird fast zuletzt angewendet und dient hauptsächlich zum Filtern von Aggregatfunktionen. LIMIT wird nach HAVING angewendet.

Beachten Sie, dass der SQL-Standard erfordert, dass HAVING nur auf Spalten in der GROUP BY-Klausel oder den Spalten verweisen muss, die in Aggregatfunktionen verwendet werden. MySQL unterstützt jedoch eine Erweiterung dieses Verhaltens und erlaubt HAVING, auf Spalten in der SELECT Liste und Spalten in äußeren Unterabfragen zu verweisen.

Als eine Nebenbemerkung möchten Sie möglicherweise auch eine explizite Inner Join dort (wie in meinem Beispiel gezeigt) anstelle der alten ANSI-89-Syntax, die Sie verwenden.