PostgreSQL:使用相同外键创建另一行之前的持续时间
PostgreSQL: Duration before another row is created with the same foreign key
有table:
id, car_id, status, created_at
有数据:
1, 180, active, 2017-04-02 10:12:00 +0600
2, 190, active, 2017-04-05 17:34:00 +0600
3, 180, inactive, 2017-05-10 16:59:00 +0600
4, 180, active, 2017-06-15 09:23:00 +0600
5, 180, inactive, 2017-07-10 19:12:00 +0600
我想知道180
第一次active
多长时间,然后inactive
多长时间,第二次active
多长时间时间.
我不是很擅长SQL,但这就是我最后的结果:
SELECT
start_log.car_id,
start_log.status,
MAX(start_log.updated_at) AS start_time,
end_log.updated_at AS end_time,
(end_log.updated_at - start_log.updated_at) AS duration
FROM
car_availabilities AS start_log
INNER JOIN
car_availabilities AS end_log ON (
start_log.car_id = end_log.car_id
AND
end_log.updated_at > start_log.updated_at
)
GROUP BY
start_log.status,
end_log.updated_at,
start_log.updated_at,
start_log.car_id
ORDER BY start_time
但是,这会产生每行之间的持续时间,而不仅仅是按时间顺序排列的下一行。
有人可以告诉我如何获得预期的结果吗?即
180, active, 2017-04-02 10:12:00 +0600, 2017-05-10 16:59:00 +0600, 38 days....
180, inactive, 2017-05-10 16:59:00 +0600, 2017-06-15 09:23:00 +0600, 35 days...
etc
谢谢❣️
给你:
WITH t AS (
SELECT *, lag(created_at, 1) OVER (PARTITION BY car_id ORDER BY created_at) as prev_state_created_at
FROM car_availabilities
)
SELECT *, (created_at - prev_state_created_at) as duration
FROM t
这是通过使用 PostgreSQL window 函数完成的。
lag
returns value evaluated at the row that is offset rows before the current row within the partition;
lag(created_at, 1) OVER (PARTITION BY car_id ORDER BY created_at)
有table:
id, car_id, status, created_at
有数据:
1, 180, active, 2017-04-02 10:12:00 +0600
2, 190, active, 2017-04-05 17:34:00 +0600
3, 180, inactive, 2017-05-10 16:59:00 +0600
4, 180, active, 2017-06-15 09:23:00 +0600
5, 180, inactive, 2017-07-10 19:12:00 +0600
我想知道180
第一次active
多长时间,然后inactive
多长时间,第二次active
多长时间时间.
我不是很擅长SQL,但这就是我最后的结果:
SELECT
start_log.car_id,
start_log.status,
MAX(start_log.updated_at) AS start_time,
end_log.updated_at AS end_time,
(end_log.updated_at - start_log.updated_at) AS duration
FROM
car_availabilities AS start_log
INNER JOIN
car_availabilities AS end_log ON (
start_log.car_id = end_log.car_id
AND
end_log.updated_at > start_log.updated_at
)
GROUP BY
start_log.status,
end_log.updated_at,
start_log.updated_at,
start_log.car_id
ORDER BY start_time
但是,这会产生每行之间的持续时间,而不仅仅是按时间顺序排列的下一行。
有人可以告诉我如何获得预期的结果吗?即
180, active, 2017-04-02 10:12:00 +0600, 2017-05-10 16:59:00 +0600, 38 days....
180, inactive, 2017-05-10 16:59:00 +0600, 2017-06-15 09:23:00 +0600, 35 days...
etc
谢谢❣️
给你:
WITH t AS (
SELECT *, lag(created_at, 1) OVER (PARTITION BY car_id ORDER BY created_at) as prev_state_created_at
FROM car_availabilities
)
SELECT *, (created_at - prev_state_created_at) as duration
FROM t
这是通过使用 PostgreSQL window 函数完成的。
lag
returns value evaluated at the row that is offset rows before the current row within the partition;
lag(created_at, 1) OVER (PARTITION BY car_id ORDER BY created_at)