连接和求和多列

Boy*_*Boy 2 t-sql database sql-server

表 TB1:

| PaymentID | CashAmount |
--------------------------
|     P1    |       3,000|
|     P2    |       5,000|
|     P3    |       8,000|
Run Code Online (Sandbox Code Playgroud)

表 TB2:

|ChequeID| PaymentID |ChequeAmount|
-----------------------------------
|   C1   |     P2    |      10,000|
|   C2   |     P1    |      15,000|
|   C3   |     P1    |       2,000|
Run Code Online (Sandbox Code Playgroud)

表 TB3:

|TransferID| PaymentID |TransferAmount|
---------------------------------------
|    T1    |     P2    |        20,000|
|    T2    |     P2    |        20,000|
|    T3    |     P1    |         3,000|
Run Code Online (Sandbox Code Playgroud)

预期结果

| PaymentID | CashAmount |ChequeAmount|TransferAmount|
------------------------------------------------------
|     P1    |       3,000|      17,000|         3,000|
|     P2    |       5,000|      10,000|        40,000|
|     P3    |       8,000|        NULL|          NULL|
Run Code Online (Sandbox Code Playgroud)

如何编写查询 JOIN 和 SUM 将所有这些表放在一起?我尝试编写简单的连接查询,但结果是错误的。

错误查询示例:

SELECT    
    TB1.PaymentID, TB1.CashAmount,
    SUM(TB2.ChequeAmount) AS ChequeAmount, 
    SUM(TB3.TransferAmount) AS TransferAmount
FROM        
    TB1
LEFT JOIN 
   TB2 ON TB1.PaymentID = TB2.PaymentID
LEFT JOIN 
   TB3 ON TB1.PaymentID = TB3.PaymentID
GROUP BY    
   TB1.PaymentID, TB1.CashAmount
Run Code Online (Sandbox Code Playgroud)

结果不正确:

| PaymentID | CashAmount | ChequeAmount | TransferAmount |
----------------------------------------------------------
|     P1    |      3,000 |      17,000  |         6,000  |
|     P2    |      5,000 |      20,000  |        40,000  |
|     P3    |      8,000 |        NULL  |          NULL  |
Run Code Online (Sandbox Code Playgroud)

Jam*_*s Z 5

您遇到的问题是您要加入具有相同 ID 的多行的表,并将数字相乘。您需要先求和,然后加入数据。假设数据可能从任何表中丢失,您还需要使用完全外连接。如果 TB1 总是有该行,那么左外连接就足够了。

你可以这样做:

SELECT      
  coalesce(TB1.PaymentID,TB2.PaymentID,TB3.PaymentID), 
  TB1.CashAmount, TB2.ChequeAmount, TB3.TransferAmount
from (
  select PaymentID, SUM(CashAmount) AS CashAmount
  from TB1 group by PaymentID
) TB1
full outer join (
  select PaymentID, SUM(ChequeAmount) AS ChequeAmount
  from TB2 group by PaymentID
) TB2 on TB1.PaymentID = TB2.PaymentID
full outer join (
  select PaymentID, SUM(TransferAmount) AS TransferAmount
  from TB3 group by PaymentID
) TB3 on isnull(TB1.PaymentID, TB2.PaymentID) = TB3.PaymentID
Run Code Online (Sandbox Code Playgroud)

SQL Fiddle 中的示例