来自多个 JOINed 表的 SUM MSSQL

SUMs from multiple JOINed tables MSSQL

我正在尝试生成一个报告,该报告根据跨多个表的动态计算显示未结余额。目前,此报告是使用服务器端语言生成的,该语言运行查询、循环查询并针对结果运行另一个查询。我的目标是在 MSSQL 中执行所有计算。

以下是包含一些示例数据的表/列:

TEST_ORDER Table

orderid    customerid   serviceamount
1001       2001                 75.00
1002       2002                 85.00
1003       2001                 25.00
1004       2003                 10.00

TEST_CUSTOMER Table

customerid    customername
2001          'Initech'
2002          'Dunder Mifflin'
2003          'Paper Street Soap Co'

TEST_ORDER项目Table

orderitemid    orderid    itemamount
5001           1001            50.00
5002           1001           150.00
5003           1002            15.00
5004           1004           200.00
5005           1004           200.00

TEST_TRANSACTION Table

transactionid    orderid    amount
9001             1001        75.00
9002             1002        25.00
9003             1002        50.00
9004             1003        55.00
9005             1001        50.00
9006             1001       150.00

我要查找的结果是:

orderid  customername           totalorder   totalpaid     balance
1001     'Initech'                  275.00      275.00        0.00
1002     'Dunder Mifflin'           100.00       75.00      -25.00
1003     'Initech'                   25.00       55.00       30.00
1004     'Paper Street Soap Co'     410.00        0.00     -410.00

这是我提出的查询:

SELECT 
    o.orderid, c.customername, o.serviceamount,
    (o.serviceamount + SUM( i.itemamount )) AS totalorder,
    SUM( t.amount ) AS totalPaid,
    ( SUM( t.amount ) - (o.serviceamount + SUM( i.itemamount )) ) AS balance

FROM 
    test_order o
    INNER JOIN test_customer c ON o.customerID = c.customerID
    LEFT OUTER JOIN test_transaction t ON o.orderID = t.orderID
    LEFT OUTER JOIN test_orderitem i ON o.orderID = i.orderID

WHERE 
    1=1

GROUP BY 
     o.orderid, c.customername, o.serviceamount,
     o.serviceamount

结果如下:

orderid  customername           totalorder   totalpaid     balance
1001     'Initech'                  675.00      550.00     -125.00
1002     'Dunder Mifflin'           115.00       75.00      -40.00
1003     'Initech'                    null       55.00        null
1004     'Paper Street Soap Co'     410.00        null        null

我遇到的问题是: 1. test_orderitem 中的记录重复,例如对于订单 1002,serviceamount 是 85 美元,只有一个 orderitem 是 15 美元,但是,总订单计算为 115 美元。我认为问题与 JOIN 迭代两次有关。 2. 'null' 在没有返回记录时出现(原因很明显)。我还没有开始研究这个,因为我一直在 MySQL 中进行测试,我想在将其带回 MSSQL 之前弄清楚 JOIN 问题。

感谢您提供的任何帮助...

试一试:

SELECT
    summary.orderid,
    summary.customername,
    summary.totalorder,
    summary.totalpaid,
    summary.totalorder - summary.totalpaid AS balance
FROM
    (SELECT
        o.orderid,
        c.customername,
        (SELECT SUM(oi.itemamount) FROM test_orderitem oi WHERE oi.orderid = o.orderid) AS totalorder,
        (SELECT IFNULL(SUM(t.amount), 0) FROM test_transaction t WHERE t.orderid = o.orderid) AS totalpaid
    FROM
        test_order o,
        test_customer c
    WHERE
        o.customerid = c.customerid) summary

对于 MS-SQL:在这里,您只需将最终查询中的 table 名称替换为您自己的名称即可。

DECLARE @Test_Order TABLE (orderid int, customerid int, serviceamount money)
INSERT INTO @Test_Order(orderid,customerid,serviceamount)
SELECT 1001,2001,75.00 UNION ALL
SELECT 1002,2002,85.00 UNION ALL
SELECT 1003,2001,25.00 UNION ALL
SELECT 1004,2003,10.00

DECLARE @Test_Customer TABLE (customerid int, customername varchar(100))
INSERT INTO @Test_Customer(customerid,customername)
SELECT 2001,'Initech' UNION ALL
SELECT 2002,'Dunder Mifflin' UNION ALL
SELECT 2003,'Paper Street Soap Co'

DECLARE @Test_OrderItem TABLE (orderitemid int, orderid int, itemamount money)
INSERT INTO @Test_OrderItem (orderitemid, orderid, itemamount)
SELECT 5001,1001,50.00 UNION ALL
SELECT 5002,1001,150.00 UNION ALL
SELECT 5003,1002,15.00 UNION ALL
SELECT 5004,1004,200.00 UNION ALL
SELECT 5005,1004,200.00

DECLARE @Test_Transaction TABLE (transactionid int, orderid int, amount money)
INSERT INTO @Test_Transaction (transactionid, orderid, amount)
SELECT 9001,1001,75.00 UNION ALL
SELECT 9002,1002,25.00 UNION ALL
SELECT 9003,1002,50.00 UNION ALL
SELECT 9004,1003,55.00 UNION ALL
SELECT 9005,1001,50.00 UNION ALL
SELECT 9006,1001,150.00


SELECT O.orderid, 
       C.customername, 
       SUM(ISNULL(O.serviceamount,0)+ISNULL(I.itemamount,0)) AS totalorder, 
       SUM(ISNULL(T.amount,0)) AS totalpaid,
       (SUM(ISNULL(T.amount,0))) - (SUM(ISNULL(O.serviceamount,0)+ISNULL(I.itemamount,0))) as balance
FROM @Test_Customer C
JOIN @Test_Order O
   ON C.customerid=O.customerid
LEFT JOIN (SELECT orderid, SUM(itemamount) AS itemamount FROM @Test_OrderItem GROUP BY orderid) I
   ON O.orderid=I.orderid
LEFT JOIN (SELECT orderid, SUM(amount) AS amount FROM @Test_Transaction GROUP BY orderid) T
   ON O.orderid=T.orderid
GROUP BY O.orderid, C.customername
ORDER BY O.orderid, C.customername

http://sqlfiddle.com/#!9/ae0be/1

SELECT 
  o.orderid,
  c.customername,
  (coalesce(o.serviceamount,0)+coalesce(i.itemsum,0)) totalorder,
  t.t_sum totalpaid,
  (coalesce(t.t_sum,0)-coalesce(o.serviceamount,0)-coalesce(i.itemsum,0)) balance
FROM TEST_ORDER o
LEFT JOIN (
  SELECT orderid, SUM(itemamount) itemsum
  FROM TEST_ORDERITEM
  GROUP BY orderid
) i
ON o.orderid = i.orderid
LEFT JOIN (
  SELECT orderid, SUM(amount) t_sum
  FROM TEST_TRANSACTION
  GROUP BY orderid
) t
ON o.orderid = t.orderid
LEFT JOIN TEST_CUSTOMER c
ON o.customerid = c.customerid
ORDER BY o.orderid