Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Nhận thời lượng dưới dạng chênh lệch dấu thời gian đối với các thay đổi vị trí lặp lại

Tạo chế độ xem có tên 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
     );

và một chế độ xem được gọi là 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
     );

sau đó sử dụng truy vấn này:

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`

Giải thích:Tôi lấy các quá trình chuyển đổi từ nhà đến cơ quan và từ cơ quan về nhà (bao gồm chuyển đổi từ nhà đến nhà / cơ quan ban đầu và nhà / cơ quan cuối cùng thành rỗng) và sau đó tham gia các quá trình chuyển đổi này trong khi kiểm tra xem chúng có liên tiếp hay không.

Đây là SQL Fiddle .

Chỉnh sửa trong câu trả lời cho nhận xét của bạn:

Dễ dàng tìm được vị trí đã biết cuối cùng cho một người và thời gian nhất định:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Truy vấn để kiểm tra xem trường có tồn tại hay không và sau đó trả về tập kết quả

  2. Đã cố đọc lỗi cuối luồng trong MySQL

  3. PHP PDO bindParam cho biến / chuỗi được sử dụng cho câu lệnh IN ...?

  4. MySQL TRÊN KHÓA DUPLICATE - id chèn lần cuối?

  5. Giám sát các truy vấn của người dùng MySQL