简体   繁体   English

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

[英]MYSQL - Update temp table with next date

I have a table with columns EquipmentNo (VARCHAR), ActionType (VARCHAR) and ActionDate (DateTime)我有一个包含 EquipmentNo (VARCHAR)、ActionType (VARCHAR) 和 ActionDate (DateTime) 列的表

When a user checks out some equipment a row would be added like this:当用户检出某些设备时,会像这样添加一行:

EquipmentNo: 123
ActionType: 'checkout'
ActionDate: '2017-02-03 09:05:27'

And when they check that equipment back in:当他们重新检查设备时:

EquipmentNo: 123
ActionType: 'checkin'
ActionDate: '2017-02-03 10:32:46'

A single piece of equipment can be checked out/checked in multiple times a day, so lets say EquipmentNo 123 had another checkout/check in later on the same day.一件设备可以在一天内多次签出/签入,因此可以说 EquipmentNo 123 在同一天晚些时候进行了另一次签出/签入。

EquipmentNo: 123
ActionType: 'checkout'
ActionDate: '2017-02-03 11:15:27'

EquipmentNo: 123
ActionType: 'checkout'
ActionDate: '2017-02-03 11:30:55'

I need to write a query which calculates the duration of all sessions (difference between checkout and corresponding check in time).我需要编写一个查询来计算所有会话的持续时间(结帐和相应的签入时间之间的差异)。 the query needs to also sum up how many sessions that equipment has had, in our case it had 2 sessions with a duration of 102 minutes.查询还需要总结设备有多少个会话,在我们的例子中它有 2 个会话,持续时间为 102 分钟。

Here is what I have so far这是我到目前为止所拥有的

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);

This yields something like这会产生类似

123 | 2017-02-03 09:05:27 | NULL | 1
123 | 2017-02-03 11:15:27 } NULL | 1

What I cannot seem to do is workout how to structure my update statement to use this table as the source and basically say "get the next check in date after sourceTable.CheckOutDate for each EquipmentNo".我似乎无法做的是锻炼如何构建我的更新语句以使用此表作为源,并基本上说“在每个 EquipmentNo 的 sourceTable.CheckOutDate 之后获取下一个签入日期”。

Let's say the table contents look like follows:假设表格内容如下所示:

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');


So, assuming the following:所以,假设如下:

  • checkout will always precede checkin for an equipment checkout总是先于checkin设备
  • Both the actions will be completed within the same day, AND这两项操作将在同一天内完成,并且
  • (An implied assumption) Every equipment that is checked out will have a check in record in the table (before this desired operation is performed) (一个隐含的假设)每个被检出的设备在表中都会有一个检入记录(在执行这个期望的操作之前)

We can write a single query to fetch all checkout events sorted first by equipment and then by time, in the order that they occurred, and assign a rank to every record fetched:我们可以编写一个查询来获取所有checkout事件,这些事件首先按设备排序,然后按时间排序,按发生的顺序排列,并为获取的每条记录分配一个rank

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

This gives:这给出:

 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

A similar query can then be written for checkin too.然后也可以为checkin编写类似的查询。

We shall then have two tables — with corresponding checkout and checkin in the comparable order — and in the sequence that they occurred, thereby giving us start and end time for each individual session for the equipments.然后,我们将有两个表 - 以可比较的顺序具有相应的checkout和检checkin - 以及它们发生的顺序,从而为我们提供设备每个单独会话的开始和结束时间。 These two corresponding tables could now simply be joined over rank and eno (equipment number) where we can compute the count of sessions as well as SUM up the time difference between each checkout and checkin :这两个相应的表现在可以简单地加入了rankeno (设备号),我们可以计算的计数sessions以及SUM了每个之间的时间差, checkoutcheckin

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)

Giving us the output as:给我们的输出为:

eno     | session_date  |   sessions    |   session_duration
--------------------------------------------------------------
123     |   2017-02-03  |       2       |   6167
123     |   2017-02-04  |       3       |   12600
124     |   2017-02-03  |       1       |   3600

The session_duration above is computed in SECOND s for the sake of simplicity as well as accuracy.为简单起见和准确性,上面的session_durationSECOND计算。

Demo link .演示链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM