mysql中带有case和if条件的迟来早去查询
我正在处理员工时间表,下面是表格。 部门mysql中带有case和if条件的迟来早去查询,mysql,case,Mysql,Case,我正在处理员工时间表,下面是表格。 部门技术支持和网络 i、 e.[8:00 AM-2:00 PM]和[1:00 PM-7:00 PM] 和正常班次[9:00 AM至6:00 PM] 现在,我想得到的是关于迟到早退的报告。 我在服务器端代码上几乎没有逻辑,但它运行得非常慢。所以我想从数据库中得到它 我在做什么 我正在生成一份报告,报告迟到早退的员工 算法 要查找员工的开始时间。。与相关部门联系。。以及各自的班次 如果员工部门是软件部门,则每天轮班一次,否则每天轮班两次 从punchin时间到注销
技术支持
和网络
i、 e.[8:00 AM-2:00 PM]
和[1:00 PM-7:00 PM]
和正常班次[9:00 AM至6:00 PM]
现在,我想得到的是关于迟到早退的报告。
我在服务器端代码上几乎没有逻辑,但它运行得非常慢。所以我想从数据库中得到它
我在做什么
我正在生成一份报告,报告迟到早退的员工
算法
08:00:00 AM
,下班时间为01:00:00 PM
选择e.emp\u id、e.emp\u name、d.dept\u name、,
案例d.部门名称
当d.dept_名称出现在(“软件”)中时
@时间:='08:55:00 AM'
其他的
@时间:='02:00:00 PM'
以“StartingTime”结尾,
@entrytime:=日期格式(el.login\u time,'%r%')为“进入办公室”`
TIMEDIFF(@entryTime,@intime)`difference`,
如果(TIMEDIFF(@entryTime,@intime)下面是这个新的简化的案例的代码,这里是旧案例
-有些列不是真正需要的,如果需要,您可以删除它们。
-注意!我必须在需要根据部门条件设置的每一列中使用CASE。另外,请注意我使用了您在提问时提出的时间安排。如果您想更改它们,请不要忘了在每个案例陈述中都这样做,否则您将无法获得回复你想要的结果
SELECT e.emp_id, d.dept_name, e.emp_name,
CASE d.dept_name
WHEN 'Tech Support' THEN '08:00:00'
WHEN 'Network' THEN '13:00:00'
ELSE '09:00:00'
END AS `StartingTime`,
CASE d.dept_name
WHEN 'Tech Support' THEN '14:00:00'
WHEN 'Network' THEN '19:00:00'
ELSE '18:00:00'
END AS `EndingTime`,
TIME_FORMAT(el.login_time, '%T') AS `Entered_into_Office`,
TIME_FORMAT(el.logout_time, '%T') AS `Left_from_Office`,
CASE d.dept_name
WHEN 'Tech Support' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('08:00:00', '%T')), '%T')
WHEN 'Network' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('13:00:00', '%T')), '%T')
ELSE
TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('09:00:00', '%T')), '%T')
END AS `Time_in_diff`,
CASE d.dept_name
WHEN 'Tech Support' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT('14:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
WHEN 'Network' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT('19:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
ELSE
TIME_FORMAT(TIMEDIFF(TIME_FORMAT('18:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
END AS `Time_out_diff`,
CASE d.dept_name
WHEN 'Tech Support' THEN TIME_FORMAT(SEC_TO_TIME(
TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('08:00:00', '%T')), '%T'))
+TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('14:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')
WHEN 'Network' THEN TIME_FORMAT(SEC_TO_TIME(
TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('13:00:00', '%T')), '%T'))
+TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('19:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')
ELSE TIME_FORMAT(SEC_TO_TIME(
TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('09:00:00', '%T')), '%T'))
+TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('18:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')
END AS `Total_time_diff`
FROM employees e
INNER JOIN department d ON d.dept_id = e.emp_dept
INNER JOIN employee_login el ON el.emp_id = e.emp_id
WHERE DATE_FORMAT(el.login_time, '%Y-%m-%d') BETWEEN '2012-01-01' AND '2013-12-31'
HAVING Total_time_diff > 0;
以下是我以前的解决方案:
在这个中,我对您的范围进行了4次查询。这是对一个部门的查询。我没有使用案例条件,但它是有效的。每个时间班次一次,所有时间表一次获取数据。对于以后的情况,我必须删除这行:按时间排序,以便联合成功。L让我知道它是否有用!
这里有一个也在employee_登录表中,第三个条目不正确。注销时间早于登录时间。所需的输出是什么?我认为使用SQL不会更快(只是猜测我不知道表的大小),您能提供您使用的“逻辑”吗(shell脚本?)也许可以改进Hanks Gimmy,执行这个语句花了2ms。我要用这个。很高兴知道。我刚刚用变量运行了SELECT。到目前为止,我还不理解正确的语法。但无法使用最后一个having子句。下面是:希望它有帮助!实际上我做了一些小修改在代码中运行代码并在项目中成功运行。在代码< >第二> /代码>和<代码>第五代码>代码>星期六<代码>,它的半天…它真的快要疯了。不管怎样,我要做。考虑一下这个SQLFiddle的选择案例:它给你一些星期六的案例选项。关于选择一个月内的特定星期六,您可以做些什么。我在一个案例中提出了一个可能的解决方案,用于技术支持。对此不确定。
dept_id | dept_name
--------------------------
1 | Software
2 | Tech Support
3 | Network
emp_id | login_time | logout_time
----------------------------------------------------------
1 | 2013-02-18 19:10:42 | 2013-02-18 21:27:37
2 | 2013-02-18 19:38:59 | 2013-02-18 22:46:14
3 | 2013-02-18 15:13:53 | 2013-01-01 18:26:39
4 | 2013-01-01 08:41:40 | 2013-01-01 016:41:40
SELECT e.emp_id, e.emp_name, d.dept_name,
CASE d.dept_name
WHEN d.dept_name IN ('Software') THEN
@intime := '08:55:00 AM'
ELSE
@intime := '02:00:00 PM'
END AS `StartingTime`,
@entrytime := DATE_FORMAT(el.login_time, '%r%') AS `Entered into Office`
TIMEDIFF(@entryTime,@intime) `difference`,
IF(TIMEDIFF(@entryTime,@intime)<'00:00:00',NULL,TIMEDIFF(@entryTime,@intime)) AS `Delay`
FROM employees e
INNER JOIN department d ON d.dept_id = e.emp_dept
INNER JOIN employee_login el ON el.emp_id = e.emp_id
WHERE DATE_FORMAT(el.login_time, '%Y-%m-%d') BETWEEN '2013-06-01' AND '2013-06-26'
ORDER BY el.login_time DESC;
SELECT e.emp_id, d.dept_name, e.emp_name,
CASE d.dept_name
WHEN 'Tech Support' THEN '08:00:00'
WHEN 'Network' THEN '13:00:00'
ELSE '09:00:00'
END AS `StartingTime`,
CASE d.dept_name
WHEN 'Tech Support' THEN '14:00:00'
WHEN 'Network' THEN '19:00:00'
ELSE '18:00:00'
END AS `EndingTime`,
TIME_FORMAT(el.login_time, '%T') AS `Entered_into_Office`,
TIME_FORMAT(el.logout_time, '%T') AS `Left_from_Office`,
CASE d.dept_name
WHEN 'Tech Support' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('08:00:00', '%T')), '%T')
WHEN 'Network' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('13:00:00', '%T')), '%T')
ELSE
TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('09:00:00', '%T')), '%T')
END AS `Time_in_diff`,
CASE d.dept_name
WHEN 'Tech Support' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT('14:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
WHEN 'Network' THEN
TIME_FORMAT(TIMEDIFF(TIME_FORMAT('19:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
ELSE
TIME_FORMAT(TIMEDIFF(TIME_FORMAT('18:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
END AS `Time_out_diff`,
CASE d.dept_name
WHEN 'Tech Support' THEN TIME_FORMAT(SEC_TO_TIME(
TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('08:00:00', '%T')), '%T'))
+TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('14:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')
WHEN 'Network' THEN TIME_FORMAT(SEC_TO_TIME(
TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('13:00:00', '%T')), '%T'))
+TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('19:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')
ELSE TIME_FORMAT(SEC_TO_TIME(
TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('09:00:00', '%T')), '%T'))
+TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('18:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')
END AS `Total_time_diff`
FROM employees e
INNER JOIN department d ON d.dept_id = e.emp_dept
INNER JOIN employee_login el ON el.emp_id = e.emp_id
WHERE DATE_FORMAT(el.login_time, '%Y-%m-%d') BETWEEN '2012-01-01' AND '2013-12-31'
HAVING Total_time_diff > 0;