来自多个JOINed表MSSQL

时间:2015-08-31 18:36:26

标签: mysql sql-server join inner-join outer-join

我正在尝试根据多个表格的动态计算生成一个显示未结余额的报表。目前,此报告是使用运行查询的服务器端语言生成的,循环查询,并针对结果运行另一个查询。我的目标是在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.当没有返回记录时出现'null'(显而易见的原因)。我还没有开始研究这个问题,因为我一直在使用MySQL进行测试,我想在将其重新引入MSSQL之前弄清楚JOIN问题。

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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