我正在尝试撰写报告。它应该给我一个特定客户的机器清单以及放入该机器的小时数和材料。
在以下示例中,我选择不同字段中的材料和小时数之和,以使问题更加清晰。但我真的想把这些材料加总一个小时,然后把它们归到机器领域。
我可以毫无问题地查询机器清单和小时费用。
SELECT CONCAT(`customer`.`PREFIX`, `wo`.`machine_id`) AS `machine`,
ROUND(COALESCE(SUM(`wohours`.`length` * `wohours`.`price`), 0), 2) AS `hours`
FROM `wo`
JOIN `customer` ON `customer`.`id`=`wo`.`customer_id`
LEFT JOIN `wohours` ON `wohours`.`wo_id`=`wo`.`id` AND `wohours`.`wo_customer_id`=`wo`.`customer_id`
AND `wohours`.`wo_machine_id`=`wo`.`machine_id` AND `wohours`.`date`>=(CURDATE() - INTERVAL DAY(CURDATE() - INTERVAL 1 DAY) DAY) - INTERVAL 11 MONTH
WHERE `wo`.`customer_id`=1
GROUP BY `wo`.`machine_id`;
这给了我正确的小时值。但是当我添加这样的材料时:
SELECT CONCAT(`customer`.`PREFIX`, `wo`.`machine_id`) AS `machine`,
ROUND(COALESCE(SUM(`wohours`.`length` * `wohours`.`price`), 0), 2) AS `hours`,
ROUND(COALESCE(SUM(`womaterial`.`multiplier` * `womaterial`.`price`), 0), 2) AS `material`
FROM `wo`
JOIN `customer` ON `customer`.`id`=`wo`.`customer_id`
LEFT JOIN `wohours` ON `wohours`.`wo_id`=`wo`.`id` AND `wohours`.`wo_customer_id`=`wo`.`customer_id`
AND `wohours`.`wo_machine_id`=`wo`.`machine_id` AND `wohours`.`date`>=(CURDATE() - INTERVAL DAY(CURDATE() - INTERVAL 1 DAY) DAY) - INTERVAL 11 MONTH
LEFT JOIN `womaterial` ON `womaterial`.`wo_id`=`wo`.`id` AND `womaterial`.`wo_customer_id`=`wo`.`customer_id`
AND `womaterial`.`wo_machine_id`=`wo`.`machine_id` AND `wohours`.`date`>=(CURDATE() - INTERVAL DAY(CURDATE() - INTERVAL 1 DAY) DAY) - INTERVAL 11 MONTH
WHERE `wo`.`customer_id`=1
GROUP BY `wo`.`machine_id`;
然后小时和材料值都不正确。
我已经读过其他线程,有类似问题的人可以通过在多个查询或子查询中拆分它来解决这个问题。但在这种情况下,我认为不可能。
感谢任何帮助。
//约翰
答案 0 :(得分:1)
你的其他阅读是正确的。您需要将它们放入自己的“子查询”中以进行连接。您可能获得无效值的原因是材料表每台机器有多个记录,因此根据小时数从原始图像中生成笛卡尔结果。并且你不知道哪个只有一个使它看起来不正确。
所以,我写过,每个最内部的查询预先聚合woHours和woMaterial将产生一个单独的记录,每个“wo_id和machine_id”在完成时加入回到wo表。这些查询中的每一个都具有您尝试为其运行的单个客户ID的标准。
然后,当重新加入工单(wo)表时,它会抓取所有记录并应用ROUND()和COALESCE(),以防没有这样的小时或材料。所以这是
之类的回报WO Machine ID Machine Hours Material
1 1 CustX 1 2 0
2 4 CustY 4 2.5 6.5
3 4 CustY 4 1.2 .5
4 1 CustX 1 1.5 1.2
最后,您现在可以将每个计算机ID的所有这些条目的SUM()汇总到一行
Machine Hours Material
CustX 1 3.5 1.2
CustY 4 3.7 7.0
SELECT
AllWO.Machine,
SUM( AllWO.Hours ) Hours,
SUM( AllWO.Material ) Material
from
( SELECT
wo.wo_id,
wo.Machine_ID,
CONCAT(customer.PREFIX, wo.machine_id) AS machine,
ROUND( COALESCE( PreSumHours.MachineHours, 0), 2) AS hours,
ROUND( COALESCE( PreSumMaterial.materialHours, 0), 2) AS material
FROM
wo
JOIN customer
ON wo.customer_id = customer.id
LEFT JOIN ( select wohours.wo_id,
wohours.wo_machine_id,
SUM( wohours.length * wohours.price ) as machinehours
from
wohours
where
wohours.wo_customer_id = 1
AND wohours.date >= ( CURDATE() - INTERVAL DAY( CURDATE() - INTERVAL 1 DAY) DAY) - INTERVAL 11 MONTH
group by
wohours.wo_id,
wohours.wo_machine_id ) as PreSumHours
ON wo.id = PreSumHours.wo_id
AND wo.machine_id = PreSumHours.wo_machine_id
LEFT JOIN ( select womaterial.wo_id,
womaterial.wo_machine_id,
SUM( womaterial.length * womaterial.price ) as materialHours
from
womaterial
where
womaterial.wo_customer_id = 1
AND womaterial.date >= ( CURDATE() - INTERVAL DAY( CURDATE() - INTERVAL 1 DAY) DAY) - INTERVAL 11 MONTH
group by
womaterial.wo_id,
womaterial.wo_machine_id ) as PreSumMaterial
ON wo.id = PreSumMaterial.wo_id
AND wo.machine_id = PreSumMaterial.wo_machine_id
WHERE
wo.customer_id = 1 ) AllWO
group by
AllWO.Machine_ID