2015-08-31 22 views
0

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

下面是表/一些示例性数据列:

TEST_ORDER表

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

TEST_CUSTOMER表

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

TEST_ORDERITEM表

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表

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,服务金额为85美元,只有15美元的订单项,然而,总订单计算为115美元。我认为问题与JOIN迭代两次有关。 2.没有记录返回时(出于显而易见的原因),显示'空'。我还没有开始这方面的工作,因为我已经在MySQL中进行了测试,并且我想在将它返回到MSSQL之前找出JOIN问题。

谢谢您也许能提供任何援助......

回答

1

对于MS-SQL:在这里,你,只需更换与最后的查询表名你自己。

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 
+0

谢谢,@JiggsJedi!该查询花了0秒钟,并返回了89,140行。乍一看,结果看起来很准确,尽管查询结果和@Alex之间存在差异。 – JDev

+0

亚历克斯和我之间的关键区别是,他做了一个左客户连接,我做了一个JOIN。亚历克斯的查询将返回没有客户记录存在的行,而我的不会。我也在orderid/customer上分组,我不会将重复订单压扁成一行。 – JiggsJedi

+0

感谢您的解释...我已经从您的查​​询和其他信息中学到了很多。干杯! – JDev

0

这给一试:

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 
+0

感谢您发布此。我能够使用它一点点,并且它返回了有用的数据,但是运行需要相当长的时间。根据我的计算,每个记录处理大约需要0.025秒。 – JDev

1

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 
+0

谢谢,@Alex!该查询花了1秒钟,返回了89,151行。 乍一看,结果看起来很准确,尽管查询结果和@JiggsJedi之间存在差异。 – JDev

+0

查看此查询帮助我提高了SQL查询技能 - 再次感谢。 – JDev