Group通过列上的特定值来加快执行时间 - SQL

时间:2015-04-08 06:39:24

标签: mysql sql sqlyog

此代码工作正常,但执行时间很长,因为attendance_03working_schedule_03具有相同的行数,因为working_schedule_03的转换计划如8 :00,9:00等等,attendance_03基于其已故员工,attendance_03拥有员工的实际时间,现在我想要的是将多个列中的一些值组合在一起working_schedule_03emp_id列和t_in(班次计划)列的t_in表,因为attendance_03未修复,员工每周更改计划,其他人已修复计划和最后一个列它具有“常规”值并取消组合“休息日”值,因此 SELECT a.emp_id, COUNT(a.a_id) AS Cymon, b.t_in AS mt_in, c.last_name, c.first_name, e.dept_name, e.dept_id, f.l_id, f.loc FROM attendance_03 AS a LEFT JOIN (SELECT * FROM working_schedule_03 WHERE d BETWEEN 16 AND 31 AND Y = 2015 AND eve="Regular") AS b ON b.emp_id = a.emp_id AND b.d = a.dd LEFT JOIN employee_personal_info AS c ON c.emp_id = a.emp_id LEFT JOIN employee_information AS d ON d.emp_id = a.emp_id LEFT JOIN departments AS e ON e.dept_id = d.department LEFT JOIN employee_location AS f ON f.l_id = d.loc WHERE a.yy = 2015 AND a.dd BETWEEN 16 AND 31 AND b.eve = "Regular" AND e.dept_id != 22 AND CASE WHEN b.t_in = "07:00" THEN HOUR(a.t_in) = "07" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "07:30" THEN HOUR(a.t_in) = "07" AND MINUTE(a.t_in) BETWEEN 31 AND 59 OR HOUR(a.t_in) = "08" AND MINUTE(a.t_in) BETWEEN 01 AND 30 WHEN b.t_in = "08:00" THEN HOUR(a.t_in) = "08" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "08:30" THEN HOUR(a.t_in) = "08" AND MINUTE(a.t_in) BETWEEN 31 AND 59 OR HOUR(a.t_in) = "09" AND MINUTE(a.t_in) BETWEEN 01 AND 30 WHEN b.t_in = "09:00" THEN HOUR(a.t_in) = "09" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "10:00" THEN HOUR(a.t_in) = "10" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "13:00" THEN HOUR(a.t_in) = "13" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "15:00" THEN HOUR(a.t_in) = "15" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "16:00" THEN HOUR(a.t_in) = "16" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "17:00" THEN HOUR(a.t_in) = "17" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "19:00" THEN HOUR(a.t_in) = "19" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "19:30" THEN HOUR(a.t_in) = "19" AND MINUTE(a.t_in) BETWEEN 31 AND 59 OR HOUR(a.t_in) = "20" AND MINUTE(a.t_in) BETWEEN 01 AND 30 WHEN b.t_in = "20:00" THEN HOUR(a.t_in) = "20" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "21:00" THEN HOUR(a.t_in) = "21" AND MINUTE(a.t_in) BETWEEN 01 AND 59 WHEN b.t_in = "23:45" THEN HOUR(a.t_in) = "23" AND MINUTE(a.t_in) BETWEEN 46 AND 59 OR HOUR(a.t_in) = "20" AND MINUTE(a.t_in) BETWEEN 01 AND 45 ELSE 0 END GROUP BY a.emp_id HAVING COUNT(a.emp_id) > 1 ORDER BY f.loc, e.dept_id, c.last_name ASC 将不会从具有休息日值的前夕列中获取行。谢谢!

working_schedule_03

CREATE TABLE `working_schedule_03` ( `id` mediumint(99) NOT NULL AUTO_INCREMENT, `start_date` datetime NOT NULL, `end_date` datetime NOT NULL, `username` varchar(255) NOT NULL, `m` varchar(9) NOT NULL, `d` varchar(9) NOT NULL, `y` varchar(9) NOT NULL, `emp_id` varchar(99) NOT NULL, `eve` varchar(99) NOT NULL, `t_in` varchar(99) NOT NULL, `t_out` varchar(99) NOT NULL, `emp_file` varchar(99) NOT NULL, `dt_plot` varchar(99) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=612993 DEFAULT CHARSET=latin1

attendance_03

CREATE TABLE `attendance_03` ( `a_id` varchar(99) NOT NULL, `t_in` varchar(99) NOT NULL, `t_b1_out` varchar(99) NOT NULL, `t_b1_in` varchar(99) NOT NULL, `t_lb_out` varchar(99) NOT NULL, `t_lb_in` varchar(99) NOT NULL, `t_b2_out` varchar(99) NOT NULL, `t_b2_in` varchar(99) NOT NULL, `t_out` varchar(99) NOT NULL, `mu` varchar(99) NOT NULL, `status` varchar(99) NOT NULL, `mm` varchar(99) NOT NULL, `dd` varchar(99) NOT NULL, `yy` varchar(99) NOT NULL, `d_out` int(2) NOT NULL, `d_b1_out` int(2) NOT NULL, `d_b1_in` int(2) NOT NULL, `d_lb_out` int(2) NOT NULL, `d_lb_in` int(2) NOT NULL, `d_b2_out` int(2) NOT NULL, `d_b2_in` int(2) NOT NULL, `emp_id` varchar(99) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1

{{1}}

1 个答案:

答案 0 :(得分:1)

添加INDEX会显着加快速度:

  • working_schedule_03将从INDEX(Y, d, eve)中受益。
  • attendance_03将从INDEX(emp_id, dd)中受益。
  • employee_personal_infoemployee_informationINDEX(emp_id)
  • departmentsINDEX(e.dept_id)
  • employee_locationINDEX(f.l_id)

除非您希望“正确”的表格缺少匹配的行,否则请删除LEFT

AND b.eve = "Regular"的第二次出现是多余的(因为第一次出现)。

子查询说SELECT *。如果你只列出必要的值(emp_id, t_in, d),那么它就会少一些东西。

我嘲笑其他事情:

  • 请勿将VARCHAR用于数字。
  • 考虑使用TIME次。 (但:00秒可能存在问题。)
  • CASE几乎可以变成

    a.t_in> = b.t_in AND a.in< b.t_in + INTERVAL 60分钟

  • 检查输出; COUNT(...)可能具有比所需更大的值。