2017-02-14 5 views
3

Ich versuche, eine Abfrage erstellen, die eine Berechnung in einer Unterabfrage, die die SUMME-Funktion und eine Gruppe von benötigt. Meine Abfrage gibt den Fehler "Unterabfrage gibt mehr als 1 Zeile zurück". Im Wesentlichen versuche ich den Betrag "fällig" für jede Bestellung zurückzugeben. Wenn die Gesamtsumme der Bestellung höher ist als die Summe von total_collected (für diese order_id) aus der Zahlungstabelle, wird der fällige Betrag fällig. Hier ist die Abfrage:Mysql Unterauswahl mit SUM() und Gruppe von

SELECT o.order_id 
    , o.server 
    , o.subtotal 
    , o.discount 
    , o.tax, o.total 
    , (SELECT (o.total - SUM(p.total_collected)) 
      from orders o 
      join payments p 
       on o.order_id = p.order_id 
     group by p.order_id) as 'Due' 
    FROM orders o 
    join payments p 
    on o.order_id = p.order_id 
WHERE...; 

Ich kann nicht enthalten ‚p.order_id‘ im Unter wählen, weil es nur eine Spalte enthalten soll. Ich verstehe, warum ich den Fehler erhalte, ich weiß nur nicht, wie ich die Subauswahl dazu bringen kann, die SUMME nur pro Order_ID durchzuführen.

+0

Können Sie Ihre erwartete Ausgabe enthalten? –

+0

Siehe http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-very-simple-sql- Abfrage – Strawberry

Antwort

2

Ohne die Struktur viel zu ändern, denke ich, dass die Unterabfrage alle Daten in den Bestell-/Zahlungstabellen betrachtet. Ich denke, Sie müssen es filtern, um nur die relevante order_id wie folgt zu betrachten.

(Ich habe auch eine SUM um den Gesamtauftrag, weil ich ziemlich sicher bin, dass wäre ohne es einen anderen Fehler geben.)

SELECT o.order_id 
    , o.server 
    , o.subtotal 
    , o.discount 
    , o.tax 
    , o.total 
    , (SELECT (SUM(o2.total) - SUM(p.total_collected)) 
      from orders o2 
      JOIN payments p 
       ON o2.order_id = p.order_id 
      WHERE o2.order_id = o.order_id) as 'Due' 
    FROM orders o 
WHERE...; 

Obwohl, wenn Sie diese so einstellen, dass es sich um eine Join verwendet statt eine Unterabfrage, ich denke du wirst bessere Leistung bekommen. Etwas wie folgt aus:

SELECT o.order_id 
    , o.server 
    , o.subtotal 
    , o.discount 
    , o.tax 
    , o.total 
    , o.total - c.Collected AS 'Due' 
    FROM orders o 
    JOIN (
     SELECT p2.order_id, SUM(p2.total_collected) AS 'Collected' 
      FROM payments p2 
     GROUP BY p2.order_id) AS c 
     ON o.order_id = c.order_id 
WHERE...; 
+1

Es besteht keine Notwendigkeit für eine Verknüpfung in der Unterabfrage. –

+0

Mit der Sub-Auswahl in der JOIN in Ihrem 2. Beispiel funktionierte großartig! Danke David! – Jdub

1

Sie brauchen keine Unterabfrage:

SELECT 
    o.order_id, 
    o.server, 
    o.subtotal, 
    o.discount, 
    o.tax, 
    o.total, 
    o.total - ifnull(sum(p.total_collected),0) As Due 
FROM orders AS o 
LEFT JOIN payments AS p ON o.order_id = p.order_id 
WHERE ... 
GROUP BY o.order_id