按单位维修的平均时间

时间:2017-06-12 15:00:51

标签: mysql sql query-optimization

我们有大约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

lineitems表:

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

在这个例子中,我们看到repair_code 3311已经完成了4次。维修之间的日子...... 116天,194天和173天。这意味着在修复ID 3311之间平均(116 + 194 + 173)/ 3 = 161天

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;

我希望按维修代码分组的输出与所述类型的修理之间的平均时间。

这就是我现在正在尝试的事情:

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

2 个答案:

答案 0 :(得分:1)

E.g:

 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;

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