2013-02-23 9 views
6

Ich habe zwei TabellenSelect Summe und innere Verknüpfung

  • Bills: id amount reference

  • Transactions: id reference amount

Die folgende SQL-Abfrage

SELECT 
    *, 
    (SELECT SUM(amount) 
    FROM transactions 
    WHERE transactions.reference = bils.reference) AS paid 
FROM bills 
GROUP BY id HAVING paid<amount 

war für einige Zeilen aus der Tabelle Bills gedacht, indem eine Spalte paid mit der Summe der Anzahl verwandter Transaktionen hinzugefügt wurde.

Es funktioniert jedoch nur, wenn für jede Rechnung mindestens eine Transaktion vorhanden ist. Andernfalls wird keine Zeile für eine transaktionslose Rechnung zurückgegeben.

Wahrscheinlich, das ist, weil ich eine innere Verbindung hätte machen sollen!

Also versuche ich folgendes:

SELECT 
    *, 
    (SELECT SUM(transactions.amount) 
    FROM transactions 
    INNER JOIN bills ON transactions.reference = bills.reference) AS paid 
FROM bills 
GROUP BY id 
HAVING paid < amount 

Dies ist jedoch für alle Zeilen den gleichen Wert der bezahlten zurück! Was mache ich falsch ?

Antwort

15

links benutzen, kommen statt einer Unterabfrage:

select b.id, b.amount, b.paid, sum(t.amount) as transactionamount 
from bills b 
left join transactions t on t.reference = b.reference 
group by b.id, b.amount, b.paid 
having b.paid < b.amount 

Edit:
Um die Summe der Transaktionen in Höhe zu vergleichen , behandeln Sie den Nullwert, den Sie erhalten, wenn keine Transaktionen vorhanden sind:

having isnull(sum(t.amount), 0) < b.amount 
+1

Aber es gibt keine "bezahlte" Spalte in "Rechnungen", dies muss als die Summe der Anzahl der Transaktionen definiert werden.Wenn ich versuche, es zu ändern, um das zu korrigieren, bekomme ich immer noch nur 'Bills'-Zeile mit mindestens einer Transaktion. – Klaus

+0

@Klaus: Ich sehe, das ist, wo Sie das von ... Die Summe wird null sein, wenn es keine Transaktionen gibt, also müssten Sie damit umgehen. Siehe Code oben. – Guffa

+0

Vielen Dank, der 'ifnull' (nicht' isnull') und linke Join schafften den Trick! – Klaus

2

Sie benötigen eine RIGHT JOIN, um alle Rechnungszeilen einzubeziehen.

EDIT So wird die endgültige Abfrage

SELECT 
    *, 
    (SELECT SUM(transactions.amount) 
    FROM transactions 
    WHERE transactions.reference = bills.reference) AS paid 
FROM bills 
WHERE paid < amount 
+0

, dass die Summe aller Transaktionen für alle Rechnungen angezeigt werden können. – Guffa

+0

Es gibt immer noch das selbe Problem wie bei meinem zweiten Versuch, wie @Guffa beschreibt. – Klaus

+0

Was, wenn Sie ersetzen "INNER JOIN Rechnungen ON" mit "WHERE" – dotNET

0

Ich weiß, dass dieser Thread alt ist, aber ich kam heute hierher, weil ich das gleiche Problem habe.

finden Sie eine andere Stelle mit der gleichen Frage: Sum on a left join SQL

Wie die Antwort sagt, auf der linken Tabelle GROUP BY verwenden. Auf diese Weise erhalten Sie alle Datensätze aus der linken Tabelle und summiert die entsprechenden Zeilen aus der rechten Tabelle.

Versuchen Sie, diese zu nutzen:

SELECT 
    *, 
    SUM(transactions.sum) 
FROM 
    bills 
RIGHT JOIN 
    transactions 
ON 
    bills.reference = transactions.reference 
WHERE 
    transactions.sum > 0 
GROUP BY 
    bills.id 
Verwandte Themen