Postgresql postgres-为T2中的每一行选择时间戳之前T1中最新的一行

Postgresql postgres-为T2中的每一行选择时间戳之前T1中最新的一行,postgresql,gps,postgis,postgresql-9.3,Postgresql,Gps,Postgis,Postgresql 9.3,我看了好几个问题,但没有找到答案。因此,如果能提供类似解决方案的答案/链接,我将不胜感激。 我有两张桌子:交通工具和活动。每辆车都有多个GPS位置——假设玩具示例中有4辆车,有11行GPS ping。但是玩具测试只有两个项目 例如车辆(每行有唯一的gid,每辆车有vehicle\u id,还有时间戳date\u time和位置geom): 事件(唯一的gid、时间戳t\u日期和位置geom): 目的是了解每次活动时的情况,哪些车辆更接近,然后优化活动车辆的分配。 因此,我想加入这些表格,以便为每

我看了好几个问题,但没有找到答案。因此,如果能提供类似解决方案的答案/链接,我将不胜感激。 我有两张桌子:交通工具和活动。每辆车都有多个GPS位置——假设玩具示例中有4辆车,有11行GPS ping。但是玩具测试只有两个项目

例如车辆(每行有唯一的
gid
,每辆车有
vehicle\u id
,还有时间戳
date\u time
和位置
geom
):

事件(唯一的
gid
、时间戳
t\u日期
和位置
geom
):

目的是了解每次活动时的情况,哪些车辆更接近,然后优化活动车辆的分配。

因此,我想加入这些表格,以便为每个事件获取最多4行(作为车辆数量),每个车辆的最后已知位置在事件前120分钟的时间段内,直到事件时间,按两者之间的距离排序。我想把它们放在同一张表中,这样我就可以按时间、地点、事件类型等进行比较

现在我被困在这里了。我知道如何找到特定时间段内(比如19:10之前)车辆的最新记录。但这不是我需要的,因为它在19:10切断了车辆表。但对于gid=13009的事件,时间为
19:04:31
,因此可能包含一个晚于事件的位置。我想要的是截至活动时间的最新位置,每个活动的位置明显不同

我试过这个:

SELECT DISTINCT ON (1)
  v.vehicle_id
  , row_number() OVER() as gid
  , st_distance(v.geom, c.geom)::float4 as distance_m
  , c.gid as c_gid 
  , v.gid as v_gid
  , c.t_date as dt_c 
  , v.date_time as dt_v 
  , (c.t_date - v.date_time) as d_t
FROM (SELECT * FROM test_c ) as c
  ,  (SELECT * FROM test_v ORDER BY date_time DESC )  v
WHERE date_time >= (c.t_date -  '120 minute' :: INTERVAL) AND date_time <= (c.t_date + '0 minute' :: INTERVAL)
ORDER BY 1, 7  DESC , 5, 6 ,  c.geom <-> v.geom ASC ;
我得到了错误的日期,并且每辆车只有一次(我猜是因为
不同的
),但我需要每个事件一次,以及适当的最后位置(因此在本例中,两个事件两次)


理想情况下,我还希望下一步为每辆车设置3个最新位置,但这可能是为了以后使用。

这就是我的理解:

select *
from (
    select distinct on (c.gid, v.vehicle_id)
        v.vehicle_id
        , row_number() over(order by v.gid) as gid
        , st_distance(v.geom, c.geom)::float4 as distance_m
        , c.gid as c_gid 
        , v.gid as v_gid
        , c.t_date as dt_c 
        , v.date_time as dt_v 
        , (c.t_date - v.date_time) as d_t
    from
        test_c c
        inner join 
        test_v v on
            date_time between c.t_date - '120 minute' :: interval and c.t_date
    order by c.gid, v.vehicle_id, v.date_time desc
) s
order by c_gid, distance_m
;
 vehicle_id | gid | distance_m | c_gid |  v_gid  |        dt_c         |        dt_v         |   d_t    
------------+-----+------------+-------+---------+---------------------+---------------------+----------
        742 |   8 |    10674.9 | 13009 | 1258089 | 2009-06-06 19:04:31 | 2009-06-06 19:03:29 | 00:01:02
       3426 |   5 |    18607.5 | 13009 | 1258008 | 2009-06-06 19:04:31 | 2009-06-06 19:02:56 | 00:01:35
       3055 |   4 |    28516.8 | 13009 | 1257939 | 2009-06-06 19:04:31 | 2009-06-06 19:02:31 | 00:02:00
        742 |  11 |     4748.6 | 13021 | 1258842 | 2009-06-06 19:08:53 | 2009-06-06 19:07:23 | 00:01:30
       3426 |  13 |    8515.65 | 13021 | 1259018 | 2009-06-06 19:08:53 | 2009-06-06 19:08:13 | 00:00:40
       3055 |  12 |    17125.8 | 13021 | 1258898 | 2009-06-06 19:08:53 | 2009-06-06 19:07:41 | 00:01:12

我看不到任何确保
DISTINCT ON(c.gid,v.vehicle\u id)
将拾取具有最小
d\t
的记录的东西。你确定它会吗?它确实有效,并选择了最后一个
dt_v
,谢谢@Clodoaldo Neto。不过@Dario:说不定可以做
WHERE v.date_time@Lizardie它将始终选择最大值。当由
发出正确的
订单时,这是一个
上的独特功能。检查手册。@Clodoaldo Neto tnx,是的,它将选择最大值
dt_v
,从而选择最小值
d_t
(即从事件到最后一个已知位置的时间距离),以下是链接
SELECT DISTINCT ON (1)
  v.vehicle_id
  , row_number() OVER() as gid
  , st_distance(v.geom, c.geom)::float4 as distance_m
  , c.gid as c_gid 
  , v.gid as v_gid
  , c.t_date as dt_c 
  , v.date_time as dt_v 
  , (c.t_date - v.date_time) as d_t
FROM (SELECT * FROM test_c ) as c
  ,  (SELECT * FROM test_v ORDER BY date_time DESC )  v
WHERE date_time >= (c.t_date -  '120 minute' :: INTERVAL) AND date_time <= (c.t_date + '0 minute' :: INTERVAL)
ORDER BY 1, 7  DESC , 5, 6 ,  c.geom <-> v.geom ASC ;
 vehicle_id | gid | distance_m | c_gid |  v_gid  |        dt_c         |        dt_v         |   d_t    
------------+-----+------------+-------+---------+---------------------+---------------------+----------
        742 |   3 |     4748.6 | 13021 | 1258842 | 2009-06-06 19:08:53 | 2009-06-06 19:07:23 | 00:01:30
       3055 |   2 |    17125.8 | 13021 | 1258898 | 2009-06-06 19:08:53 | 2009-06-06 19:07:41 | 00:01:12
       3426 |   1 |    8515.65 | 13021 | 1259018 | 2009-06-06 19:08:53 | 2009-06-06 19:08:13 | 00:00:40
(3 rows)
select *
from (
    select distinct on (c.gid, v.vehicle_id)
        v.vehicle_id
        , row_number() over(order by v.gid) as gid
        , st_distance(v.geom, c.geom)::float4 as distance_m
        , c.gid as c_gid 
        , v.gid as v_gid
        , c.t_date as dt_c 
        , v.date_time as dt_v 
        , (c.t_date - v.date_time) as d_t
    from
        test_c c
        inner join 
        test_v v on
            date_time between c.t_date - '120 minute' :: interval and c.t_date
    order by c.gid, v.vehicle_id, v.date_time desc
) s
order by c_gid, distance_m
;
 vehicle_id | gid | distance_m | c_gid |  v_gid  |        dt_c         |        dt_v         |   d_t    
------------+-----+------------+-------+---------+---------------------+---------------------+----------
        742 |   8 |    10674.9 | 13009 | 1258089 | 2009-06-06 19:04:31 | 2009-06-06 19:03:29 | 00:01:02
       3426 |   5 |    18607.5 | 13009 | 1258008 | 2009-06-06 19:04:31 | 2009-06-06 19:02:56 | 00:01:35
       3055 |   4 |    28516.8 | 13009 | 1257939 | 2009-06-06 19:04:31 | 2009-06-06 19:02:31 | 00:02:00
        742 |  11 |     4748.6 | 13021 | 1258842 | 2009-06-06 19:08:53 | 2009-06-06 19:07:23 | 00:01:30
       3426 |  13 |    8515.65 | 13021 | 1259018 | 2009-06-06 19:08:53 | 2009-06-06 19:08:13 | 00:00:40
       3055 |  12 |    17125.8 | 13021 | 1258898 | 2009-06-06 19:08:53 | 2009-06-06 19:07:41 | 00:01:12