2017-06-12 48 views
2

我们有大约275,000个单位。这些单位有修理记录详细说明不同的修理。我试图找出在任何给定单位之间平均维修时间是多少。按单位修理的平均时间

我们有一个workorders表,其中包含unit_no和一个包含修复代码的lineitems表。例如:

工作订单表:

wo_master_number | unit_no | wo_date 
100    | 50  | 2016-02-15 
101    | 51  | 2016-06-10 
102    | 52  | 2016-12-21 
103    | 53  | 2017-06-12 

了LineItem表:

wo_master_number | repair_code 
    100    | 3311 
    100    | 4358 
    101    | 3311 
    102    | 3311 
    103    | 3311 

在这个例子中,我们可以看到repair_code 3311已经做了4次。维修之间的时间间隔为116天,194天和173天。该装置(116 + 194 + 173)上平均/ 3 =161天3311

CREATE TABLE `wo_workorders` (
    `unique_key` bigint(20) NOT NULL AUTO_INCREMENT, 
    `wo_master_number` int(11) DEFAULT NULL, 
    `revision_status` char(1) DEFAULT NULL, 
    `wo_status` char(35) DEFAULT NULL, 
    `workorder_no` char(25) DEFAULT NULL, 
    `unit_no` char(15) DEFAULT NULL, 
    [omitted for brevity] 

    PRIMARY KEY (`unique_key`), 
    KEY `workorder_no` (`workorder_no`), 
    KEY `unit_no` (`unit_no`), 
    KEY `wo_date` (`workorder_date`), 
    [omitted for brevity] 

) ENGINE=InnoDB AUTO_INCREMENT=1860068 DEFAULT CHARSET=latin1; 

CREATE TABLE `wo_lineitems` (
    `unique_key` bigint(20) NOT NULL AUTO_INCREMENT, 
    `wo_unique_key` bigint(20) DEFAULT NULL, 
    `wo_master_number` int(11) DEFAULT NULL, 
    `line_item_unique_key` bigint(20) DEFAULT NULL, 
    `rep_code` char(10) DEFAULT NULL, 
    [omitted for brevity] 

    PRIMARY KEY (`unique_key`), 
    KEY `wo_unique_key` (`wo_unique_key`), 
    KEY `wo-master_revision` (`wo_master_number`,`revision_number`), 
    KEY `rep_code` (`rep_code`), 
    [omitted for brevity] 

) ENGINE=InnoDB AUTO_INCREMENT=8935142 DEFAULT CHARSET=latin1; 

ID的修复之间我想通过修复代码的平均时间,所述类型的维修之间分组的输出。

这里就是我想现在:

SELECT n.rep_code,AVG(diff) avg 
FROM ( 
    SELECT a.rep_code,DATEDIFF(MIN(b.workorder_date), a.workorder_date) diff 
    FROM 
     (SELECT o.workorder_date 
       , x.rep_code , 
       o.wo_master_number, 
       o.unit_no 
      FROM wo_workorders o 
      JOIN wo_lineitems x ON x.wo_master_number = o.wo_master_number 
      -- where o.workorder_date > 20170601 
     ) a 
     JOIN 
     (SELECT o.workorder_date 
       , x.rep_code , 
       o.wo_master_number, 
       o.unit_no 
      FROM wo_workorders o 
      JOIN wo_lineitems x ON x.wo_master_number = o.wo_master_number 
      -- where o.workorder_date > 20170601 
     ) b ON b.rep_code = a.rep_code 
     AND b.workorder_date > a.workorder_date 
     -- where a.workorder_date > 20170601 -- added for speed 
    GROUP 
     BY a.wo_master_number 
     , a.unit_no 
     , a.workorder_date 
     , a.rep_code 
) n 
GROUP BY rep_code; 

(sqlfiddle:http://sqlfiddle.com/#!9/28682e/1

除了它太慢运行: explain plan

+0

参见:[?为什么要我为了什么,在我看来是一个非常简单的SQL查询提供MCVE(https://meta.stackoverflow.com/questions/333952/why-should-i-提供一个mcve为什么似乎对我来说是一个非常简单的sql查询) – Strawberry

+0

@Strawberry谢谢,现在会做 – Ted

+0

请提供解释。 (一个upvote也不错) – Strawberry

回答

0

你可以只计算平均值:

select li.repair_code, avg(datediff(min(wo_date), max(wo_date))) 
from workorders wo join 
    lineitems li 
    on li.wo_master_number = wo.wo_master_number 
group by li.repair_code; 
+1

datediff之间....什么?最小和最大工作日期? – Ted

+0

'错误代码:1111.组函数的使用无效' – Ted

1

例如:

SELECT n.repair_code 
    , AVG(diff) avg 
    FROM 
    ( 
    SELECT a.repair_code 
    , DATEDIFF(MIN(b.workorder_date), a.workorder_date) diff 
    FROM 
    (SELECT o.* 
      , x.repair_code 
     FROM workorders o 
     JOIN lineitems x 
      ON x.wo_master_number = o.wo_master_number 
    ) a 
    JOIN 
    (SELECT o.* 
      , x.repair_code 
     FROM workorders o 
     JOIN lineitems x 
      ON x.wo_master_number = o.wo_master_number 
    ) b 
    ON b.repair_code = a.repair_code 
    AND b.workorder_date > a.workorder_date 
GROUP 
    BY a.wo_master_number 
    , a.unit_no 
    , a.workorder_date 
    , a.repair_code 
) n 
GROUP BY repair_code; 
+0

我认为,至少在理论上,这就是我想要的。唯一的问题是,它的运行速度太慢(我在几千个工作单上运行它,耗时约7200秒 - 总共有160万个工作单元。) – Ted

+1

@Ted所以让我们从基础开始。在所有表上定义PRIMARY KEY,然后更新您的问题,为所有相关表提供SHOW CREATE TABLE语句,以及针对上述的EXPLAIN结果。 – Strawberry

+0

已更新。有一些索引(我不知道)还有一件事我们可以限制的是'where wo_status ='C'' – Ted