2017-02-03 13 views
1

ユーザが行は次のように追加されるいくつかの機器をチェックアウトするとき、私は列EquipmentNo(VARCHAR)、ACTIONTYPE(VARCHAR)とActionDate(日時)MYSQL - 次の日付の更新一時テーブル

持つテーブルを持っています。

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分で2セッションでした。ここで

は、これまで

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 

のようなものがソースとしてこの表を使用する私の更新ステートメントを構築する方法をトレーニングで得私が持っているものです基本的に「各EquipmentNoのsourceTable.CheckOutDateの後の日付で次のチェックを取得する」と言います。

+0

チェックアウトとチェックインは常に交互に行われると思いますか? – McNets

+0

はい - チェックインは、チェックインの日付の前に、重複はありません。 – andrewb

+0

機器は、例えば23:55:00でチェックアウトされ、翌日、02:00:00にチェックイン可能ですか'?セッションはどの日に帰されるのですか? –

答えて

1

のは、テーブルの内容は次のようになりましょうが、以下:

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イベントを取得するために、単一のクエリを書くことができますが、時間によって第1の機器によって、その後ソート、順番に彼らが発生し、フェッチされたすべてのレコードへ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のために書かれている。同等の順にcheckoutcheckinを対応する - -

我々は、2つのテーブルを持たなければならないと、彼らが発生した順序で、これにより、機器の個々のセッションの開始時刻と終了私たちを与えます。私たちに出力を与える

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) 

:これら二つの対応のテーブルは今、単に私たちはそれぞれcheckoutcheckin間の時間差までsessionsの数だけでなく、SUMを計算することができrankeno(機器番号)を介して結合することができ

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

+0

パーフェクト!正確に私が必要なもの – andrewb

+1

@andrewbを確認してくれてありがとう!連続するイベント/タイムスタンプ/行と何か関係があることを示すために質問のタイトルを更新するとよいでしょうか?乾杯! –

関連する問題