Mysql员工使用时差中断时间历史记录
我有带有Mysql员工使用时差中断时间历史记录,mysql,sql,mariadb,mariadb-10.3,Mysql,Sql,Mariadb,Mariadb 10.3,我有带有inoutmode标志的员工生物识别日志数据。我试图得到详细的休息时间列表和时间差 inoutmode4作为中断,5作为中断 INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (105, '2019-09-19', '14:00:13', 4); INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `s
inoutmode
标志的员工生物识别日志数据。我试图得到详细的休息时间列表和时间差
inoutmode
4作为中断,5作为中断
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (105, '2019-09-19', '14:00:13', 4);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (105, '2019-09-19', '16:07:08', 4);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (105, '2019-09-19', '16:07:18', 5);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (235, '2019-09-19', '15:44:26', 4);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (235, '2019-09-19', '16:37:58', 4);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (235, '2019-09-19', '20:01:11', 5);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (235, '2019-09-19', '20:01:25', 5);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (235, '2019-09-19', '20:30:29', 4);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (326, '2019-09-19', '15:58:30', 4);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (326, '2019-09-19', '19:34:09', 5);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (327, '2019-09-19', '15:44:19', 5);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (327, '2019-09-19', '15:55:37', 4);
INSERT INTO `tbl_downloadentry` (`EmpMachineID`, `shift_date`, `AttenTime`, `InOutMode`) VALUES (327, '2019-09-19', '19:59:38', 4);
这是我想要的输出
我尽了最大的努力来取得成果。以下是我尝试的查询:
SELECT l2.empmachineid,
l2.shift_date,
l2.attentime,
l2.inoutmode
FROM tbl_downloadentry AS l2
WHERE l2.inoutmode IN ( 5, 4 )
AND l2.shift_date = "2019-09-19"
ORDER BY l2.empmachineid,
l2.shift_date,
l2.attentime ASC
我的MySQL版本=10.3.17-MariaDB-1-log
SELECT l2.EmpMachineID, l2.shift_date, l2.InOutMode,
case when l2.InOutMode=5 then l2.AttenTime END AS BreakOut,
case when l2.InOutMode=4 then l2.AttenTime END AS BreakIn
FROM tbl_downloadentry AS l2
WHERE l2.InOutMode IN (5, 4) AND l2.shift_date="2019-09-19"
ORDER BY l2.EmpMachineID, l2.shift_date, l2.AttenTime ASC
我使用case条件到达了部分记录,但inoutmode中的4和5应该是单行,以计算时间差。任何想法
非常感谢您的建议。如果我正确理解了问题,您希望将“4”记录与“5”记录关联起来。您的结果集似乎与示例数据关系不大,因此很难遵循 以下方法将每个4/5与最近的一个相关联。它通过分配一个分组来实现这一点,每个“4”向上计数,每个“5”向下计数 然而,这并不是完整的解决方案,因为当一系列的“4”和“5”连续出现时,可能会有多个起伏。因此,它分配了一个二级分组,以将其分解
SELECT EmpMachineID, shift_date,
MAX(CASE WHEN InOutMode = 4 THEN AttenTime END),
MAX(CASE WHEN InOutMode = 5 THEN AttenTime END)
FROM (SELECT dl.*,
SUM(InOutMode = group_first_InOutMode) OVER (PARTITION BY dl.EmpMachineID, dl.shift_date, dl.grouping ORDER BY dl.AttenTime) as secondary_grouping
FROM (SELECT dl.*,
FIRST_VALUE(InOutMode) OVER (PARTITION BY dl.EmpMachineID, dl.shift_date, dl.grouping ORDER BY dl.AttenTime) as group_first_InOutMode
FROM (SELECT dl.*,
SUM( CASE WHEN InOutMode = 4 THEN 1 WHEN InOutMode = 5 THEN -1 END) OVER
(PARTITION BY dl.EmpMachineID, dl.shift_date
ORDER BY dl.AttenTime
) -
(CASE WHEN InOutMode = 5 THEN -1 ELSE 0 END) as grouping -- subtract out "5"s on current row
FROM tbl_downloadentry dl
WHERE dl.InOutMode IN (5, 4) AND dl.shift_date = '2019-09-19'
) dl
) dl
) dl
GROUP BY EmpMachineID, shift_date, grouping, secondary_grouping;
这是一种利用MariaDB 10.2+和MySQL 8+中提供的函数和窗口的方法
- 当特定行的InOutMode模式为
时,这意味着这是一个4
中断时间。现在,我们使用
LAG()。排序是基于时间定义的。因此,如果前一行的
模式是InOutMode
,这意味着我们有一个相应的5
时间用于此break\u-in
时间,否则break\u-out
null
- 对于
模式为InOutMode
的行,也遵循类似的过程。这次唯一的区别是我们使用了5
函数;因为我们需要获得立即的下一行,并检查它是否是LEAD()
中断
- 现在,我们只需要将这个结果集用作一个和
不同的
结果集(因为对于同时存在break\u in和break\u out的每种情况,我们都会有重复的行)。此外,在外部查询中,我们可以使用函数计算时间差
EmpID=235
执行以下查询:
SELECT
DISTINCT
dt.*,
TIMEDIFF(dt.break_out, dt.break_in) AS diff
FROM
(
SELECT
EmpMachineID,
shift_date,
CASE InOutMode
WHEN 4 THEN AttenTime -- this is break_out row
WHEN 5 THEN -- this is break_in row, find the break_out if exists
CASE
WHEN LEAD(InOutMode) OVER w = 4
THEN LEAD(AttenTime) OVER w
END
END AS break_out,
CASE InOutMode
WHEN 5 THEN AttenTime -- this is break_in row
WHEN 4 THEN -- this is break_out row, find the break_in if exists
CASE
WHEN LAG(InOutMode) OVER w = 5
THEN LAG(AttenTime) OVER w
END
END AS break_in
FROM tbl_downloadentry
WHERE EmpMachineID = 235
AND InOutMode IN (4,5)
AND shift_date = '2019-09-19'
WINDOW w AS (PARTITION BY EmpMachineID
ORDER BY AttenTime ASC)
) AS dt;
结果
| EmpMachineID | shift_date | break_out | break_in | diff |
| ------------ | ---------- | --------- | -------- | -------- |
| 235 | 2019-09-19 | 15:44:26 | | |
| 235 | 2019-09-19 | 16:37:58 | | |
| 235 | 2019-09-19 | | 20:01:11 | |
| 235 | 2019-09-19 | 20:30:29 | 20:01:25 | 00:29:04 |
您是否尝试过任何查询?请编辑此问题并添加您的尝试,以便我们能将您推向正确的方向。感谢您的回复@Madhur。我正在尽最大努力取得成果。下面我提到了这个查询。
``从tbl_downloadentry中选择l2.EmpMachineID、l2.shift_date、l2.Attentitime、l2.InOutMode作为l2,其中l2.InOutMode在(5,4)和l2.shift_date=“2019-09-19”按l2.EmpMachineID、l2.shift_date、l2.Attentitime ASC排序````请输入问题,并以正确的格式在此处添加查询。不要对这样的事情使用评论。另外,您的MySQL服务器版本是什么?运行
选择版本()在你的mysql客户端上,请用版本详细信息更新问题。我只需更新示例输出。查询确定后,它将应用于所有EmpMachineID。您所需的输出与数据不一致-“15:44:26”在插入数据中给定了模式4(中断),在所需的输出列中显示为中断。您是否错误地交换了所需输出中的列?@YathavSriTechnology welcome:)我刚才已经对答案进行了解释;仔细阅读以正确理解运行MariaDB 10.1+@YathavSriTechnology No.中提供的LEAD()和LAG()窗口函数的任何可能性。此查询在我的开发pc中成功工作,但在客户端pc中不工作。MariaDB 10.1.13是否有其他方法根据10.1.13更改查询?
| EmpMachineID | shift_date | break_out | break_in | diff |
| ------------ | ---------- | --------- | -------- | -------- |
| 235 | 2019-09-19 | 15:44:26 | | |
| 235 | 2019-09-19 | 16:37:58 | | |
| 235 | 2019-09-19 | | 20:01:11 | |
| 235 | 2019-09-19 | 20:30:29 | 20:01:25 | 00:29:04 |