如何仅使用MySQL Query获取Employees的休息时间

时间:2014-02-13 08:29:57

标签: mysql

id      staff_ID        STAFFNAME             CARDTIME
39618   1203024        BARAYUGA M.     2014-02-03 08:44:02
39618   1203024        BARAYUGA M.     2014-02-03 12:20:02
39618   1203024        BARAYUGA M.     2014-02-03 12:50:49
39618   1203024        BARAYUGA M.     2014-02-03 17:33:44
39622   1203056        LEONES M.       2014-02-03 12:00:21
39622   1203056        LEONES M.       2014-02-03 12:23:19
39622   1203056        LEONES M.       2014-02-03 13:22:33
39622   1203056        LEONES M.       2014-02-03 15:30:11 

上面是我的数据库中的tbl_staff表,有没有办法可以获得每个员工的总休息时间?仅使用Mysql查询。

这是我现在使用的示例查询。

SELECT 
  DATE,
  STAFFNAME, 
  LOGIN, LOGOUT, 
  SUCCESSFUL, 
  TIME,
  NUMBEROFTIME, 
  FIND_IN_SET(LOGIN,TIME),
  FIND_IN_SET(LOGOUT,TIME)
FROM 
(
    SELECT   
      DATE( CARDTIME ) AS DATE, 
      STAFFNAME,  
      MIN( CARDTIME )  AS LOGIN,  
      MAX( cardtime ) AS LOGOUT, 
      CASE 
        WHEN COUNT( CARDTIME ) %2 =0 THEN 1 
        ELSE 0 
      END AS  'SUCCESSFUL', 
      GROUP_CONCAT(DISTINCT(CARDTIME) ORDER BY (CARDTIME) )  AS TIME,
      COUNT(CARDTIME) as NUMBEROFTIME
    FROM tbl_staff
    GROUP BY STAFFNAME, DATE( CARDTIME )
) AS x

我已经研究了如何获得休息时间,但示例数据与我的不同,LOGINLOGOUT

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

MySQL允许您编写如下查询:

SELECT
  id, staff_ID, STAFFNAME,
  timediff(t3,t2) AS Break
FROM (
  SELECT
    id, staff_ID, STAFFNAME,
    DATE(CARDTIME) as carddate,
    SUBSTRING_INDEX(
      SUBSTRING_INDEX(
        GROUP_CONCAT(CARDTIME order by CARDTIME),
        ',',
        3),
      ',',
      -1) t3,
    SUBSTRING_INDEX(
      SUBSTRING_INDEX(
      GROUP_CONCAT(CARDTIME order by CARDTIME),
      ',',
      2),
    ',',
    -1) t2
  FROM
    tablename
  GROUP BY
    id, staff_ID, STAFFNAME,
    DATE(CARDTIME)
  ) s

它不是太优化而不是SQL标准,你还应该确保每天有四个卡片时间。但它应该返回你需要的结果。

请参阅小提琴here

修改

如果雇员可以拥有少于或多于4个卡片时间条目,您应该考虑使用此查询:

SELECT *
FROM (
  SELECT
    id,
    staff_ID,
    STAFFNAME,
    DATE(CARDTIME) AS card_day,
    timediff(next_CARDTIME,CARDTIME) As t_diff,
    CASE WHEN
      CASE WHEN next_CARDTIME IS NULL THEN @n:=-1 ELSE @n:=@n+1 END MOD 2 = 0
      THEN 'Work' ELSE 'Break'
    END AS type
  FROM (
    SELECT
      t1.id,
      t1.staff_ID,
      t1.STAFFNAME,
      t1.CARDTIME,
      MIN(t2.CARDTIME) next_CARDTIME
    FROM
      tablename t1 LEFT JOIN tablename t2
      ON (t1.id, t1.staff_ID) = (t2.id, t2.staff_ID)
         AND DATE(t1.cardtime)=DATE(t2.cardtime)
         AND t1.cardtime<t2.cardtime
    GROUP BY
      t1.id, t1.staff_ID, t1.STAFFNAME, t1.CARDTIME
    ORDER BY
      t1.id, t1.staff_ID, t1.STAFFNAME, t1.CARDTIME
    ) s, (SELECT @n:=-1) r
  ) s
WHERE t_diff IS NOT NULL

当然,如果cardtime条目的数量是奇数,那么当天的最后一个条目将是休息。看看这个fiddle