mysql - 按列上的特定值分组以获得更快的执行时间 - SQL

标签 mysql sql sqlyog

此代码完美运行,但执行时间较长,因为 attendance_03working_schedule_03 具有相同的行数,后者确实需要每一行,因为 working_schedule_03 有一个轮类时间表,如 8:00、9:00 等等,它是 attendance_03 其迟到员工的基础,attendance_03 有一个实际时间员工,现在我想要的是在 working_schedule_03 表中的多个列中对一些值进行分组,该表是 emp_id 列和 t_in(shift schedule) 列,因为t_in 不固定,员工每周都会更改时间表,其他人有固定的 sched 和 last eve 列,它们具有“常规”值并取消分组“休息日”值,因此 attendance_03 不会从具有休息日值的 eve 列中获取行。谢谢!

 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

最佳答案

添加索引会显着加快速度:

  • working_schedule_03 将从 INDEX(Y, d, eve) 中受益。
  • attendance_03 将从 INDEX(emp_id, dd) 中受益。
  • employee_personal_infoemployee_information:INDEX(emp_id)
  • 部门:INDEX(e.dept_id)
  • employee_location:INDEX(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 MINUTE

  • 检查输出; COUNT(...) 的值可能比需要的大。

关于mysql - 按列上的特定值分组以获得更快的执行时间 - SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29507631/

相关文章:

MySQL查询优化: how can I speed up this query?

Mysql排序日期格式

mysql - 在 Sqlyog 中格式化语句的键盘快捷方式?

mysql - 使用外键

mysql - SQL - 子字符串并同时选择 *

MySQL Workbench 导入/导出 : ERROR 2003 (HY000): Can't Connect to MySQL server on 'localhost' (110)

MYSQL - 在时间范围之间选择

mysql - 如何获取表中最高订单的计数?

php - html iframe 中的字符错误

sql - 字符串或二进制数据将被截断。该语句已终止。简单错误