4

我正在工作员工时间表,下面是表格。部门员工有两个班次Tech SupportNetwork[ 8:00 AM to 2:00 PM ][ 1:00 PM to 7:00 PM ]

和正常班次[ 9:00 AM to 6:00 PM ]

现在,我想得到关于迟到早退的人的报告。我对服务器端代码的逻辑很少,但它的运行速度非常慢。所以我想从数据库中制作它。

我在做什么

我正在生成报告,迟到早退的员工

算法

  1. 查找员工开始时间..与部门..和各自的班次
  2. 如果员工部门是软件,则进行一次轮班,否则每天进行两次轮班
  3. 从打卡时间和注销时间..找到员工班次。
  4. 如果员工轮班在第一班,请使用 intime as08:00:00 AM和 outtime as01:00:00 PM
  5. 如果员工轮班在第二班,则使用 intime as02:00:00 PM和 outtime as07:00:00 PM
  6. 如果员工班次在正常班次下,请使用 intime as08:55:00 AM和 outtime as06:00:00 PM

然后找到,现在找到它的login_time并登录

雇员

emp_id  |   emp_name    |   emp_dept
--------------------------------------
1       |   Billy J     |   1
2       |   Sarah k     |   2
3       |   Takashi M   |   3
4       |   Matsuzaka   |   2

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

SQL查询,我试过了,有点不完整..

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;
4

1 回答 1

3

下面是这个新的 简化CASE Fiddle的代码。这是旧的 CASE Fiddle
- 有些列并不是真正需要的,如果需要,您可以删除它们。
-注意!我必须在每个需要根据部门条件设置的列中使用CASE 。另外,请注意,我使用了您在提出问题时提出的时间安排。如果您想更改它们,请不要忘记在每个 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;

以下是我以前的解决方案:
在这个SQLFiddle 中,我为您的范围进行了 4 次查询。这是一个部门的查询。我没有使用 CASE 条件,但它有效。每个时间班次一个,一个为所有时间表采集数据。对于后来我不得不删除这一行:ORDER BY Time_in_diff DESC;为了使UNION成功。让我知道它是否有帮助!这是一个带有准备好的语句的解决方案

于 2013-06-29T14:35:02.483 回答