[英]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
设备 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
:这两个相应的表现在可以简单地加入了rank
和eno
(设备号),我们可以计算的计数sessions
以及SUM
了每个之间的时间差, checkout
和checkin
:
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_duration
在SECOND
计算。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.