计算在国家/地区花费的时间
Calculate time spend in countries
我正在尝试寻找一种方法来检测在国家/地区花费的汽车时间。
这是我 table 跟踪 when/how 存储的记录:
car_id, seen, country
001 2021-02-03 germany
001 2021-02-21 germany
001 2021-03-02 germany
001 2021-03-10 france
001 2021-03-21 germany
003 ...
输出的想法可能在以下领域:
car_id, seen, country, interval_in_same_country
001 2021-02-03 germany 0 days
001 2021-02-21 germany 18 days
001 2021-03-02 germany 27 days
001 2021-03-10 france 0 days
001 2021-03-21 germany 0 days
003 ...
也许还有更好的,但这是我最初的想法。
有关如何进行此类计算的任何帮助?
你可以使用延迟window函数
select
car_id,
seen,
country,
case
when interval_in_same_country < 0 then (interval_in_same_country * (-1))
when interval_in_same_country is null then 0
else interval_in_same_country
end as interval_in_same_country
from
(select * ,
case
when lag(country) over (order by seen) <> country then 0
else DATE_PART('day', seen::timestamp) - DATE_PART('day', lag(seen,1) over(order by car_id)::timestamp)
end as interval_in_same_country
from table) t
您可以使用带有三个参数和一些条件逻辑的 lag()
:
select t.*,
(case when lag(country) over (order by car_id) = country
then seen - lag(seen, 1, seen) over (order by car_id)
else interval '0 day'
end)
from t;
使用 window 函数 lag()
和 sum()
WITH j AS (
SELECT DISTINCT ON (car_id,seen,country) *,
coalesce(CASE
WHEN LAG(country) OVER (ORDER BY seen) <> country THEN 0
ELSE
seen-LAG(seen) OVER (PARTITION BY car_id,country ORDER BY seen )
END,0) AS days
FROM t
ORDER BY seen ASC)
SELECT car_id,seen,country,
CASE WHEN days <> 0 AND LAG(days) OVER w <> 0 THEN
sum(days) OVER w
ELSE days
END interval_in_same_country
FROM j
WINDOW w AS (PARTITION BY car_id,country ORDER BY seen ASC)
ORDER BY seen ;
演示:db<>fiddle
我正在尝试寻找一种方法来检测在国家/地区花费的汽车时间。
这是我 table 跟踪 when/how 存储的记录:
car_id, seen, country
001 2021-02-03 germany
001 2021-02-21 germany
001 2021-03-02 germany
001 2021-03-10 france
001 2021-03-21 germany
003 ...
输出的想法可能在以下领域:
car_id, seen, country, interval_in_same_country
001 2021-02-03 germany 0 days
001 2021-02-21 germany 18 days
001 2021-03-02 germany 27 days
001 2021-03-10 france 0 days
001 2021-03-21 germany 0 days
003 ...
也许还有更好的,但这是我最初的想法。 有关如何进行此类计算的任何帮助?
你可以使用延迟window函数
select
car_id,
seen,
country,
case
when interval_in_same_country < 0 then (interval_in_same_country * (-1))
when interval_in_same_country is null then 0
else interval_in_same_country
end as interval_in_same_country
from
(select * ,
case
when lag(country) over (order by seen) <> country then 0
else DATE_PART('day', seen::timestamp) - DATE_PART('day', lag(seen,1) over(order by car_id)::timestamp)
end as interval_in_same_country
from table) t
您可以使用带有三个参数和一些条件逻辑的 lag()
:
select t.*,
(case when lag(country) over (order by car_id) = country
then seen - lag(seen, 1, seen) over (order by car_id)
else interval '0 day'
end)
from t;
使用 window 函数 lag()
和 sum()
WITH j AS (
SELECT DISTINCT ON (car_id,seen,country) *,
coalesce(CASE
WHEN LAG(country) OVER (ORDER BY seen) <> country THEN 0
ELSE
seen-LAG(seen) OVER (PARTITION BY car_id,country ORDER BY seen )
END,0) AS days
FROM t
ORDER BY seen ASC)
SELECT car_id,seen,country,
CASE WHEN days <> 0 AND LAG(days) OVER w <> 0 THEN
sum(days) OVER w
ELSE days
END interval_in_same_country
FROM j
WINDOW w AS (PARTITION BY car_id,country ORDER BY seen ASC)
ORDER BY seen ;
演示:db<>fiddle