假設表的內容看起來如下:
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');
因此,假設如下:
checkout
總是先checkin
爲設備
- 所採取的行動將是在同一天內完成,並且
- (暗示假設)已簽出將有創紀錄的檢查表中(執行此期望的操作之前,每個設備)
我們可以編寫一個查詢來獲取所有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
這給:
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
類似的查詢可以TH也寫爲checkin
。
我們應該再有兩個表 - 與可比的順序上相對應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)
給人的輸出:這兩個相應的表格現在可以簡單地在rank
和eno
(設備號),我們可以計算的sessions
計數以及SUM
了每個checkout
和checkin
之間的時間差來加入爲:
eno | session_date | sessions | session_duration
--------------------------------------------------------------
123 | 2017-02-03 | 2 | 6167
123 | 2017-02-04 | 3 | 12600
124 | 2017-02-03 | 1 | 3600
上述session_duration
計算在SECOND
S表示簡單起見以及精度。
Demo link。
我可以假設簽出和簽入將總是圖案? – McNets
是的 - 結賬將始終在入住日期之前,沒有重疊 – andrewb
是否有可能在23:55:00'檢出設備,並在第二天,在02:00點退房'?會議將歸因於哪一天? –