MYSQL-使用下一个日期更新临时表

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(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在同一天晚些时候有另一次签出/签入

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!您认为更新问题的标题以表明它与连续事件/时间戳/行有关是好的吗?干杯