MYSQL-使用下一个日期更新临时表
我有一个列为EquipmentNo(VARCHAR)、ActionType(VARCHAR)和ActionDate(DateTime)的表 当用户签出某些设备时,将添加一行,如下所示:MYSQL-使用下一个日期更新临时表,mysql,Mysql,我有一个列为EquipmentNo(VARCHAR)、ActionType(VARCHAR)和ActionDate(DateTime)的表 当用户签出某些设备时,将添加一行,如下所示: EquipmentNo: 123 ActionType: 'checkout' ActionDate: '2017-02-03 09:05:27' 当他们检查设备时: EquipmentNo: 123 ActionType: 'checkin' ActionDate: '2017-02-03 10:32:46'
EquipmentNo: 123
ActionType: 'checkout'
ActionDate: '2017-02-03 09:05:27'
当他们检查设备时:
EquipmentNo: 123
ActionType: 'checkin'
ActionDate: '2017-02-03 10:32:46'
一件设备一天可以签出/签入多次,因此假设EquipmentNo 123在同一天晚些时候有另一次签出/签入
EquipmentNo: 123
ActionType: 'checkout'
ActionDate: '2017-02-03 11:15:27'
EquipmentNo: 123
ActionType: 'checkout'
ActionDate: '2017-02-03 11:30:55'
我需要编写一个查询来计算所有会话的持续时间(签出和相应签入时间之间的差异)。查询还需要总结该设备有多少个会话,在我们的例子中,它有两个会话,持续时间为102分钟
这是我到目前为止所拥有的
CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 AS (
SELECT EquipmentNo, MIN( ActionDate ) AS CheckOutDate,
NULL AS CheckInDate, COUNT( * ) AS Sessions
FROM EquipmentSessions WHERE ActionType = 'checkout' GROUP BY EquipmentNo, ActionDate);
这会产生类似的结果
123 | 2017-02-03 09:05:27 | NULL | 1
123 | 2017-02-03 11:15:27 } NULL | 1
我似乎无法解决的是如何构造我的update语句以使用此表作为源,并基本上说“在sourceTable.CheckOutDate之后获取每个设备的下一个签入日期否”。假设表内容如下所示:
CREATE TABLE eqp (eno int, action_type varchar(20), action_date timestamp);
INSERT INTO eqp VALUES(124, 'checkout', '2017-02-03 09:00:00');
INSERT INTO eqp VALUES(123, 'checkout', '2017-02-03 09:05:27');
INSERT INTO eqp VALUES(124, 'checkin', '2017-02-03 10:00:00');
INSERT INTO eqp VALUES(123, 'checkin', '2017-02-03 10:32:46');
INSERT INTO eqp VALUES(123, 'checkout', '2017-02-03 11:15:27');
INSERT INTO eqp VALUES(123, 'checkin', '2017-02-03 11:30:55');
INSERT INTO eqp VALUES(123, 'checkout', '2017-02-04 09:00:00');
INSERT INTO eqp VALUES(123, 'checkin', '2017-02-04 10:00:00');
INSERT INTO eqp VALUES(123, 'checkout', '2017-02-04 15:00:00');
INSERT INTO eqp VALUES(123, 'checkin', '2017-02-04 17:00:00');
INSERT INTO eqp VALUES(123, 'checkout', '2017-02-04 18:30:00');
INSERT INTO eqp VALUES(123, 'checkin', '2017-02-04 19:00:00');
因此,假设如下:
始终在设备的签出
之前签入
- 这两项行动将在同一天内完成,并且
- (隐含的假设)每台已签出的设备都将在表中有一个签入记录(在执行此所需操作之前)
签出
事件,这些事件先按设备排序,然后按时间排序,按照事件发生的顺序排序,并为获取的每个记录分配一个等级
:
SELECT @checkoutrank := @checkoutrank + 1 AS rank, eno, action_type, action_date
FROM eqp, (SELECT @checkoutrank := 0) r
WHERE action_type='checkout'
ORDER BY eno ASC, action_date ASC
这使得:
rank | eno | action_type | action_date
----------------------------------------------------------
1 | 123 | checkout | 2017-02-03 09:05:27
2 | 123 | checkout | 2017-02-03 11:15:27
3 | 123 | checkout | 2017-02-04 09:00:00
4 | 123 | checkout | 2017-02-04 15:00:00
5 | 123 | checkout | 2017-02-04 18:30:00
6 | 124 | checkout | 2017-02-03 09:00:00
然后也可以为签入编写类似的查询然后,我们将有两个表——相应的
checkout
和checkin
以可比的顺序——以及它们发生的顺序,从而为我们提供设备每个单独会话的开始和结束时间。这两个对应的表现在可以简单地通过rank
和eno
(设备编号)连接起来,在这里我们可以计算会话的计数
,以及总和
计算每个签出
和签入
之间的时间差:
SELECT checkin.eno, DATE(checkin.action_date) AS session_date,
COUNT(*) AS sessions,
SUM(TIMESTAMPDIFF(SECOND, checkout.action_date, checkin.action_date))
AS sesssion_duration
FROM
(
SELECT @checkoutrank := @checkoutrank + 1 AS rank, eno, action_type, action_date
FROM eqp, (SELECT @checkoutrank := 0) r
WHERE action_type='checkout'
ORDER BY eno ASC, action_date ASC
) checkout
INNER JOIN
(
SELECT @checkinrank := @checkinrank + 1 AS rank, eno, action_type, action_date
FROM eqp, (SELECT @checkinrank := 0) r
WHERE action_type='checkin'
ORDER BY eno ASC, action_date ASC
) checkin
ON checkout.rank = checkin.rank
AND checkout.eno = checkin.eno
GROUP BY checkin.eno, DATE(checkin.action_date)
给我们的输出为:
eno | session_date | sessions | session_duration
--------------------------------------------------------------
123 | 2017-02-03 | 2 | 6167
123 | 2017-02-04 | 3 | 12600
124 | 2017-02-03 | 1 | 3600
为了简单和准确,上面的会话\u持续时间
以秒
s计算
.我是否可以假设签出和签入总是会发生变化?是-签出总是在签入日期之前,没有重叠。设备可能在,比如说,
23:55:00
签出,然后在第二天的02:00:00
签入?会议将于哪一天举行?让我们说同一天是完美的!正是我所需要的谢谢你的确认,@andrewb!您认为更新问题的标题以表明它与连续事件/时间戳/行有关是好的吗?干杯