复杂的全外加入

时间:2013-06-03 18:18:09

标签: sql join coalesce

叹息......任何人都可以帮忙吗?在下面的SQL查询中,我得到的结果不正确。 [LaborDetail]

中有三(3)份劳工记录
  • 小时/费用
  • 2.75 / 50.88
  • 2.00 / 74.00
  • 1.25 / 34.69

[WorkOrderInventory] ​​

中有两(2)条材料记录
  • 材料成本
  • 42.75
  • 35.94

问题是查询错误地返回以下内容:

sFunction      cntWO    sumLaborHours   sumLaborCost    sumMaterialCost
ROBOT HARNESS   1         12              319.14              236.07

我在查询中做错了什么导致总和成倍增加?正确的值是sumLaborHours = 6,sumLaborCost = 159.57,sumMaterialCost = 78.69。谢谢你的帮助。

SELECT CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
    THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END AS sFunction,
(SELECT COUNT(*)
    FROM work_orders
        FULL OUTER JOIN Work_Orders_Archived
        ON work_orders.order_number = Work_Orders_Archived.order_number
    WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630') AS cntWO,
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
FROM work_orders
    FULL OUTER JOIN Work_Orders_Archived
    ON work_orders.order_number = Work_Orders_Archived.order_number
    LEFT OUTER JOIN
        (SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
            FROM LaborDetail) AS LD
            ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
    LEFT OUTER JOIN
        (SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
            FROM WorkOrderInventory) AS WOI
            ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630'
GROUP BY CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
        THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END
ORDER BY sFunction

3 个答案:

答案 0 :(得分:1)

在执行完全连接到" WorkOrderInventory"时,尝试在派生表子查询中使用SUM函数。像这样...

select 
...  
 sum(hrs) as sumlaborhrs, 
 sum(cost) as sumlaborcost, 
 -- calculate material cost in subquery 
 summaterialcost
from labordetail a
full outer join 
 (select ordernumber, sum(materialcost) as summaterialcost
  from WorkOrderInventory 
  group by ordernumber
 ) b on a.workorderno = b.ordernumber

我创建了一个简单的sql fiddle来演示这个(为了示例,我简化了您的查询)

答案 1 :(得分:0)

最好的猜测是工单在其中一个表中出现不止一次。尝试这些查询以检查两个最明显的候选表中的重复项:

select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
      from work_orders
      group by order_number
     ) t
group by cnt
order by 1;

select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
      from work_orders_archived
      group by order_number
     ) t
group by cnt
order by 1;

如果其中一行返回cnt不为1的行,则表格中有重复项。

答案 2 :(得分:0)

在我看来,work_orderswork_orders_archived包含相同的内容,您需要两个表,就好像它们是一个表一样。因此,您可以代替加入创建UNION并使用它,就像它是一个表一样:

select location as sfunction
from
(select location
  from work_orders
union  location
  from work_orders_archived)

然后你用它来加入其余的。你在做什么DBMS?您可以使用WITH。但这在MYSQL上并不存在。

with wo as 
(select location as sfunction, order_number
  from work_orders
union  location, order_number
  from work_orders_archived)
select sfunction,
count(*) 
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
from wo
    LEFT OUTER JOIN
        (SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
            FROM LaborDetail) AS LD
            ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
    LEFT OUTER JOIN
        (SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
            FROM WorkOrderInventory) AS WOI
            ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
where wo.order_number = '919630'
group by sfunction
order by sfunction