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]

现在,我想得到的是关于迟到早退的报告。 我在服务器端代码上几乎没有逻辑,但它运行得非常慢。所以我想从数据库中得到它

我在做什么 我正在生成一份报告,报告迟到早退的员工

算法
  • 要查找员工的开始时间。。与相关部门联系。。以及各自的班次
  • 如果员工部门是软件部门,则每天轮班一次,否则每天轮班两次
  • 从punchin时间到注销时间。。查找员工班次
  • 如果员工轮班时间在第一班,则使用上班时间为
    08:00:00 AM
    ,下班时间为
    01:00:00 PM
  • 如果员工轮班时间在第二班,则将上班时间设置为下午02:00:00,下班时间设置为下午07:00
  • 如果员工轮班是在正常轮班情况下,则将上班时间设置为上午08:55:00,下班时间设置为下午06:00
  • 然后发现, 现在找到它的登录时间和日志

    桌子 员工 部门 员工登录 SQL查询,我试过了,有点不完整。。
    选择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;