既存のテーブルにクエリを実行して必要なデータを生成する非常に簡単な方法はないと思います。ただし、ユーザーセッションの2番目のテーブルを維持することはできます(もちろん、これには、後で別のセッションタイムアウト期間を使用するレポートが必要になった場合に、テーブルを最初から再作成する必要があるという欠点があります)。
CREATE TABLE Sessions (
user_id INT,
session_start TIMESTAMP,
session_end TIMESTAMP,
PRIMARY KEY (user_id, session_start),
FOREIGN KEY (user_id, session_start) REFERENCES TrackingRaw(user_id, event_time),
FOREIGN KEY (user_id, session_end ) REFERENCES TrackingRaw(user_id, event_time)
);
次を使用するトリガーを使用して、このようなテーブルに自動的にデータを入力/更新できますINSERT ... SELECT ... ON DUPLICATE KEY UPDATE
。
CREATE TRIGGER after_insert_TrackingRaw AFTER INSERT ON TrackingRaw FOR EACH ROW
INSERT INTO Sessions (user_id, session_start, session_end)
SELECT NEW.user_id,
IFNULL(MAX(session_start), NEW.event_time),
NEW.event_time
FROM Sessions
WHERE user_id = NEW.user_id
AND session_end >= NEW.event_time - INTERVAL 2 MINUTE
ON DUPLICATE KEY UPDATE
session_start = session_start,
session_end = NEW.event_time;
次に、目的のクエリ結果を取得するには、次のようにします。
SELECT user_id, session_end - session_start AS seconds_interval FROM Sessions;
sqlfiddleでそれを参照してください。
アップデート
Sessions
さらに熟考した後、もちろん、ストアドプロシージャ内にそのようなテーブルを作成できます。
CREATE PROCEDURE getSessions(IN secs INT) READS SQL DATA BEGIN
DECLARE no_more_rows BOOLEAN;
DECLARE cur CURSOR FOR
SELECT user_id, event_time FROM TrackingRaw ORDER BY event_time ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_rows = TRUE;
DROP TEMPORARY TABLE IF EXISTS Sessions;
CREATE TEMPORARY TABLE Sessions (
user_id INT,
session_start TIMESTAMP,
session_end TIMESTAMP,
PRIMARY KEY(user_id,session_start),
FOREIGN KEY(user_id,session_start) REFERENCES TrackingRaw(user_id,event_time),
FOREIGN KEY(user_id,session_end ) REFERENCES TrackingRaw(user_id,event_time)
);
OPEN cur;
the_loop: LOOP
FETCH cur INTO @u, @t;
IF no_more_rows THEN
CLOSE cur;
LEAVE the_loop;
END IF;
INSERT INTO Sessions
SELECT @u, IFNULL(MAX(session_start), @t), @t
FROM Sessions
WHERE user_id = @u AND session_end >= @t - secs
ON DUPLICATE KEY UPDATE
session_start = session_start, session_end = @t
END LOOP the_loop;
DEALLOCATE PREPARE stmt;
SELECT user_id, session_end - session_start AS seconds_interval FROM Sessions;
DROP TEMPORARY TABLE Sessions;
END;;
そして、出力を取得するには:
CALL getSessions(120); -- for a 2 minute (120 second) timeout