我有一个名为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 |
...
SQL小提琴:http://www.sqlfiddle.com/#!12/7c92e/1(PG 9.2仅因为9.3在SQL Fiddle上重载了。)
start_time
和end_time
都是时间戳。
我想做的事情是在同一个日历日或{{1}的下一个日历日发现涉及同一vehicle_id
的行程start_time
以前的旅行。
例如,系统会返回ID为end_time
和1
的行,因为:
2
' 2
与start_time
在同一日历日(2014-06-24
)进行;和1
很有可能这在SQL中是不明智的。任何有关Postgres职能的建议,提示或指示欢迎。
答案 0 :(得分:2)
访问"之前的"可以使用window functions完成行。在这种情况下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;
"以前"只有你提供排序顺序才有意义。从您的描述中,听起来好像您想使用id
列来确定行的顺序。但是,如果您可以轻松地将其更改为使用start_date
。
该语句计算到下一行和上一行的天数差异。如果仅采用与之前的差异,则不会返回id=1
的行。
表达式start_time::date
只是将时间戳转换为删除时间部分的日期。这也会导致差异是整数值(以天为单位)而不是interval
。
SQLFiddle:http://www.sqlfiddle.com/#!12/7c92e/5