计算在国家/地区花费的时间

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