来自多个 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
我正在尝试生成一个报告,该报告根据跨多个表的动态计算显示未结余额。目前,此报告是使用服务器端语言生成的,该语言运行查询、循环查询并针对结果运行另一个查询。我的目标是在 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