sql >> データベース >  >> RDS >> Mysql

繰り返される場所の変更のタイムスタンプの差として期間を取得する

    home_to_workというビューを作成します:

    CREATE VIEW `home_to_work`AS 
        SELECT b.name, NULL AS `home`, b.timestamp AS `work`
        FROM mytable b
        WHERE b.location = 'work'
                AND NOT EXISTS (
                        SELECT 1 FROM mytable m
                        WHERE b.name = m.name AND m.timestamp < b.timestamp
         )
        UNION ALL
        SELECT a.name, a.timestamp AS `home`, b.timestamp AS `work`
        FROM mytable a
        JOIN mytable b
                ON a.name = b.name AND a.location = 'home' AND b.location = 'work'
         AND a.timestamp < b.timestamp
         AND NOT EXISTS (
                        SELECT 1 FROM mytable m
                        WHERE a.name = m.name AND m.timestamp > a.timestamp AND m.timestamp < b.timestamp
         )
        UNION ALL
        SELECT a.name, a.timestamp AS `home`, NULL AS `work`
        FROM mytable a
        WHERE a.location = 'home'
                AND NOT EXISTS (
                        SELECT 1 FROM mytable m
                        WHERE a.name = m.name AND m.timestamp > a.timestamp
         );
    

    そしてwork_to_homeと呼ばれるビュー:

    CREATE VIEW `work_to_home`AS 
        SELECT b.name, NULL AS `work`, b.timestamp AS `home`
        FROM mytable b
        WHERE b.location = 'home'
            AND NOT EXISTS (
                SELECT 1 FROM mytable m
                WHERE b.name = m.name AND m.timestamp < b.timestamp
         )
        UNION ALL
        SELECT a.name, a.timestamp AS `work`, b.timestamp AS `home`
        FROM mytable a
        JOIN mytable b
            ON a.name = b.name AND a.location = 'work' AND b.location = 'home'
         AND a.timestamp < b.timestamp
         AND NOT EXISTS (
                SELECT 1 FROM mytable m
                WHERE a.name = m.name AND m.timestamp > a.timestamp AND m.timestamp < b.timestamp
         )
        UNION ALL
        SELECT a.name, a.timestamp AS `work`, NULL AS `home`
        FROM mytable a
        WHERE a.location = 'work'
            AND NOT EXISTS (
                SELECT 1 FROM mytable m
                WHERE a.name = m.name AND m.timestamp > a.timestamp
         );
    

    次に、次のクエリを使用します:

    SELECT `name`, location, `from`, `until`, duration
    FROM (
        SELECT h2w.`name`, 'work' AS `location`, h2w.work AS `from`, w2h.work AS `until`, TIMESTAMPDIFF(second, h2w.`work`, w2h.`work`) AS `duration`
        FROM home_to_work h2w
        JOIN work_to_home w2h
          ON h2w.name = w2h.name AND h2w.work < w2h.work AND NOT EXISTS (
            SELECT 1 FROM mytable m
            WHERE h2w.name = m.name AND m.location = 'home' AND m.timestamp > h2w.work AND m.timestamp < w2h.work
        )
    
        UNION ALL
    
        SELECT w2h.`name`, 'home' AS `location`, w2h.home AS `from`, h2w.home AS `until`, TIMESTAMPDIFF(second, w2h.`home`, h2w.`home`) AS `duration`
        FROM work_to_home w2h
        JOIN home_to_work h2w
          ON w2h.name = h2w.name AND w2h.home < h2w.home AND NOT EXISTS (
            SELECT 1 FROM mytable m
            WHERE w2h.name = m.name AND m.location = 'work' AND m.timestamp > w2h.home AND m.timestamp < h2w.home
        )
    ) locations
    ORDER BY `name`, `from`
    

    説明:自宅から職場への移行、および職場から自宅への移行(最初のnullから自宅/職場および最終的な自宅/職場からnullを含む)を導き出し、それらが連続していることを確認しながら、これらの移行に参加します。

    これが SQLFiddle です。 。

    コメントへの返信で編集:

    特定の人と時間の最後の既知の場所を取得するのは簡単です:

    SELECT location
    FROM mytable
    WHERE `name` = 'John' AND timestamp < '2015-07-08 11:07:00'
    ORDER BY timestamp DESC
    LIMIT 1
    



    1. MySQLは、固定値と複数の選択結果を持つデータを挿入します

    2. mysqldumpのベストプラクティス:パート1 –MySQLの前提条件

    3. MySQLの概念:セッションと接続

    4. PHP:mysqli_fetch_array()の結果を2回ループできないのはなぜですか?