2010-05-02 31 views
14

Tôi cố gắng để trả về một danh sách các tài khoản với dư, Kết quả của họ và thu nhậpLàm thế nào để SUM cột trên nhiều điều kiện trong một GROUP BY

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

Dưới đây là những gì tôi đang có. Ai đó có thể giải thích nơi tôi đang đi sai?

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] 

CẬP NHẬT

đã sửa chữa các t2 trái tham gia cú pháp theo bình luận dưới đây.

Kết quả tôi mong đợi là hiển nhiên từ câu hỏi. Đối với 6 tài khoản, SQL sẽ trả về 6 tài khoản với Số dư, Thu nhập và Kết quả của tài khoản đó.

Sự cố với SQL mà tôi cung cấp là các số sai! Theo các ý kiến ​​tôi nghĩ rằng vấn đề bắt nguồn từ việc tham gia nhiều lần mà là tổng hợp số tiền không chính xác.

+0

Không nên tham gia TRANSACTION t2 trên t2 như ở trên t2.ACCOUNT_ID = a.ACCOUNT_ID? {Vui lòng chỉnh sửa câu hỏi. Được quảng bá để nhận xét từ câu trả lời của Neil Moss dưới đây} – SAMills

Trả lời

17

Vì bạn không cho chúng tôi biết what's going wrong (có nghĩa là mô tả hành vi bạn nhận được ngoài việc mô tả hành vi bạn mong đợi), thật khó để nói ở đâu, nhưng có một vài khả năng. Neil chỉ ra một. Khác là vì bạn tham gia vào bảng giao dịch ba lần, bạn đang ghép nối các giao dịch với các giao dịch và nhận được các lần lặp lại. Thay vào đó, hãy tham gia vào bảng giao dịch một lần duy nhất và thay đổi cách bạn tổng hợp cột Amount.

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] 

Bạn có thể sử dụng CASE biểu thức như một sự thay thế dễ đọc hơn cho phép nhân:

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 không có hàm 'LEAST' và' GREATEST'. – Thomas

+0

@Thomas: vâng, điều đó thật tệ. Thay đổi để không sử dụng chúng. – outis

+0

Câu trả lời cuối cùng được cung cấp trong câu hỏi của tôi. Tuy nhiên, chấp nhận câu trả lời của bạn được sử dụng SUM (CASE WHEN ... cho các giá trị OUTCOME và INCOME. – David

6

Ý của bạn là:

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

Chỉ thiếu END trên câu lệnh CASE. – David

+0

Được bầu chọn nhưng không thể chấp nhận câu trả lời vì câu hỏi của tôi mơ hồ về kết quả và chỉ nên tham gia trên bảng giao dịch một lần. – David

+0

@David Liddle: Thx đã cập nhật. –

1

nên không phải là tham gia cho GIAO DỊCH T2 được trên t2 như trong on t2.ACCOUNT_ID = a.ACCOUNT_ID?

2

Tôi không chắc chắn lý do tại sao bạn sẽ cần nhiều tham gia. Bạn có thể không đơn giản làm điều gì đó như:

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] 
Các vấn đề liên quan