SQL/Postgres:跨行比较时间戳

SQL/Postgres:跨行比较时间戳,sql,postgresql,timestamp,timespan,Sql,Postgresql,Timestamp,Timespan,我有一个名为trips的表,看起来如下: id | vehicle_id | start_time | end_time | ----+------------+---------------------+---------------------+ 1 | 1 | 2014-06-16 22:00:00 | 2014-06-24 03:30:00 | 2 | 1 | 2014-06-24 05:00:00 |

我有一个名为
trips
的表,看起来如下:

 id | vehicle_id | start_time          | end_time            |
----+------------+---------------------+---------------------+
  1 |          1 | 2014-06-16 22:00:00 | 2014-06-24 03:30:00 |
  2 |          1 | 2014-06-24 05:00:00 | 2014-06-28 05:00:00 |
  3 |          2 | 2014-06-23 02:00:00 | 2014-06-30 04:00:00 |
 ...
SQLFiddle:(第9.2页只是因为当时SQLFiddle上的9.3被重载。)

开始时间
结束时间
都是时间戳

我想做的是查找涉及相同
车辆id
的行程,其中后续行程的
开始时间
发生在前一行程的
结束时间
的同一日历日或下一日历日

例如,将返回上面ID为
1
2
的行,因为:

  • 2
    开始时间
    1
    在同一日历日(
    2014-06-24
    )进行;及
  • 两行具有相同的
    车辆id
在SQL中这样做很可能是不明智的。欢迎向相关Postgres函数提供任何建议、提示或指针。

可以使用访问“上一行”中的值。在这种情况下,
lag()
函数

select id, vehicle_id, start_time, end_time
from (
  select id, vehicle_id, start_time, end_time,
         start_time::date - lag(end_time::date) over (partition by vehicle_id order by start_time) as diff_to_prev,
         end_time::date - lead(start_time::date) over (partition by vehicle_id order by start_time) as diff_to_next
  from trips
) t
where diff_to_prev = 0
   or diff_to_next = 0;
“previous”仅在同时提供排序顺序时才有意义。根据您的描述,听起来好像您想使用
id
列来确定行的顺序。但如果您可以轻松地将其更改为使用
start\u date

该语句计算到下一行和上一行的天数差。如果只取与上一行的差异,则不会返回id为1的行

表达式
start\u time::date
只是将时间戳转换为日期以删除时间部分。这也会导致差值为整数值(以天为单位),而不是
间隔


SQLFIDLE:

非常感谢!我觉得这是正确的方法。不过,我没有得到任何结果:@Aupajo:我认为您希望它按
id
排序,这显然是错误的。只需将
按id下单
更改为
按开始时间下单
,您就会得到id:20,2246925344不知道您为什么期望52975355,因为5297在2014-10-27结束,而5355在2014-10-28开始,这显然不是同一天。太好了,谢谢!我们的目标是找到“在同一个日历日或下一个日历日进行的旅行”-但您已经向我展示了足够多,我可以从这里开始:)谢谢。如果您想包括第二天,您可以将条件更改为
diff\u to\u next