2010-05-02 10 views
14

Ich versuche, eine Liste von Konten mit ihren Guthaben, Outcome und EinkommenWie Spalten auf mehreren Bedingungen in einer Gruppe Summe durch

Account   Transaction 
-------   ----------- 
AccountID   TransactionID 
BankName   AccountID 
Locale    Amount 
Status 

Zum Rückkehren hier ist das, was ich im Moment habe. Kann mir jemand erklären, wo ich falsch liege?

select 
    a.ACCOUNT_ID, 
    a.BANK_NAME, 
    a.LOCALE, 
    a.STATUS, 
    sum(t1.AMOUNT) as BALANCE, 
    sum(t2.AMOUNT) as OUTCOME, 
    sum(t3.AMOUNT) as INCOME 
from ACCOUNT a 
left join TRANSACTION t1 on t1.ACCOUNT_ID = a.ACCOUNT_ID 
left join TRANSACTION t2 on t2.ACCOUNT_ID = a.ACCOUNT_ID and t2.AMOUNT < 0 
left join TRANSACTION t3 on t3.ACCOUNT_ID = a.ACCOUNT_ID and t3.AMOUNT > 0 
group by a.ACCOUNT_ID, a.BANK_NAME, a.LOCALE, a.[STATUS] 

UPDATE

Haben Sie korrigiert die T2-Syntax gemäß dem Kommentar unten kommen gelassen.

Die Ausgabe, die ich erwarte, wird hoffentlich von der Frage offensichtlich. Für 6 Konten sollte die SQL 6 Konten mit ihrem Kontostand, Einkommen und Ergebnis dieses Kontos zurückgeben.

Das Problem mit der SQL, die ich zur Verfügung stellte, war, dass die Zahlen falsch sind! Nach den Kommentaren denke ich, das Problem ergibt sich aus dem Beitritt mehrere Male, die die Beträge falsch summiert.

+0

Sollte der Join für TRANSACTION t2 nicht auf t2 sein wie auf t2.ACCOUNT_ID = a.ACCOUNT_ID? {Bitte bearbeiten Sie die Frage. Gefördert von Neil Moss 'Antwort unten zu kommentieren – SAMills

Antwort

17

Da Sie uns what's going wrong nicht mitgeteilt haben (das heißt, beschreiben Sie das Verhalten, das Sie neben der Beschreibung des von Ihnen erwarteten Verhaltens erhalten), ist es schwer zu sagen, wo, aber es gibt ein paar Möglichkeiten. Neil weist auf eins hin. Ein weiterer Grund ist, dass Sie, da Sie dreimal an der Transaktionstabelle teilnehmen, Transaktionen mit Transaktionen paaren und Wiederholungen erhalten. Treten Sie stattdessen einmal in die Transaktionstabelle ein und ändern Sie, wie Sie die Spalte Amount zusammenfassen.

Select 
    a.ACCOUNT_ID, 
    a.BANK_NAME, 
    a.LOCALE, 
    a.STATUS, 
    sum(t.AMOUNT) as BALANCE, 
    sum((t.AMOUNT < 0) * t.AMOUNT) As OUTGOING, 
    sum((t.AMOUNT > 0) * t.AMOUNT) As INCOMING 
From ACCOUNT a 
Left Join TRANSACTION t On t.ACCOUNT_ID = a.ACCOUNT_ID 
Group By a.ACCOUNT_ID, a.BANK_NAME, a.LOCALE, a.[STATUS] 

Sie können CASE Ausdrücke als lesbarer Alternative zu den Multiplikationen verwenden:

Select 
    a.ACCOUNT_ID, 
    a.BANK_NAME, 
    a.LOCALE, 
    a.[STATUS], 
    sum(t.AMOUNT) As BALANCE, 
    sum(CASE WHEN t.AMOUNT < 0 THEN t.AMOUNT ELSE 0 end) As OUTCOME, 
    sum(CASE WHEN t.AMOUNT > 0 THEN t.AMOUNT ELSE 0 end) As INCOME 
From ACCOUNT a 
Left Join [TRANSACTION] t On t.ACCOUNT_ID = a.ACCOUNT_ID 
Group By a.ACCOUNT_ID, a.BANK_NAME, a.LOCALE, a.[STATUS] 
+0

@outis - AFAIK, t-sql hat keine 'LEAST'- oder' GREATEST' -Funktion. – Thomas

+0

@Thomas: Nun, das ist scheiße. Geändert, um sie nicht zu benutzen. – outis

+0

Bereitgestellte endgültige Antwort in meiner Frage. Akzeptiert Ihre Antwort jedoch verwendet SUM (CASE WHEN ... für OUTCOME und Einkommen Werte. – David

6

Meinten Sie:

select 
    a.ACCOUNT_ID, 
    a.BANK_NAME, 
    a.LOCALE, 
    a.STATUS, 
    sum(t1.AMOUNT) as BALANCE, 
    sum(CASE WHEN t2.AMOUNT < 0 THEN t2.Amount ELSE 0 END) as OUTCOME, 
    sum(CASE WHEN t3.AMOUNT > 0 THEN t3.Amount ELSE 0 END) as INCOME 
from 
    ACCOUNT a 
    left join TRANSACTION t1 on t1.ACCOUNT_ID = a.ACCOUNT_ID 
    left join TRANSACTION t2 on t2.ACCOUNT_ID = a.ACCOUNT_ID 
    left join TRANSACTION t3 on t3.ACCOUNT_ID = a.ACCOUNT_ID 
group by 
    a.ACCOUNT_ID, a.BANK_NAME, a.LOCALE, a.[STATUS] 
+0

Nur fehlt das Ende der CASE-Anweisung. – David

+0

Upvoted, konnte aber keine Antwort akzeptieren, da meine Frage bezüglich der Ergebnisse vage war und nur einmal in die Transaktionstabelle aufgenommen werden sollte. – David

+0

@David Liddle: Thx haben aktualisiert. –

1

Sollte die Verbindung nicht für Transaktion T2 auf t2 wie in on t2.ACCOUNT_ID = a.ACCOUNT_ID sein?

2

Ich bin nicht sicher, warum Sie das mehrere Joins benötigen würde. Könnten Sie nicht einfach etwas tun:

Select 
    a.ACCOUNT_ID 
    , a.BANK_NAME 
    , a.LOCALE 
    , a.STATUS 
    , Sum (t.Amount) As Balance 
    , Sum(Case When t.Amount < 0 Then Amount End) As Outcome 
    , Sum(Case When t.Amount > 0 Then Amount End) As Income 
From ACCOUNT a 
    Left Join TRANSACTION t 
     On t.ACCOUNT_ID = a.ACCOUNT_ID 
Group By a.ACCOUNT_ID, a.BANK_NAME, a.LOCALE, a.[STATUS] 
Verwandte Themen