比较具有相同 ID 的行的日期时间,return 仅比较日期时间差异小于 4 小时的列

Compare datetime of rows with same ID, return only columns with datetime difference less than 4 hours

我真的很难解决这个问题。任何帮助将不胜感激!

table:

+------+----------+--------------------+--------+-------------------+
|Ref   |Dept      |DeptTime            |Arr     |ArrTime            |
+------+----------+--------------------+--------+-------------------+
|1     |New York  |2015-02-01 08:00:00 |Boston  |2015-02-01 09:00:00|
|1     |Boston    |2015-02-01 10:00:00 |Chicago |2015-02-01 11:00:00|
|1     |Chicago   |2015-02-01 12:00:00 |Dallas  |2015-02-01 13:00:00|
|1     |Dallas    |2015-02-02 11:00:00 |Seattle |2015-02-02 13:00:00|
|2     |London    |2015-02-01 04:00:00 |Berlin  |2015-02-01 16:00:00|
|2     |Berlin    |2015-02-02 18:00:00 |Moscow  |2015-02-02 23:00:00|
+------+----------+--------------------+--------+-------------------+

此 table 显示多站旅程。如果到达和离开之间的停留时间少于 4 小时,则应视为同一行程的一部分。目的地应为下一次出发时间大于四小时的首次到达时间。在那种情况下,我想显示出发城市和出发时间,以及最终到达目的地和到达时间。您可以在该问题的底部看到所需的输出示例。

我认为查询应该做的是 select 具有相同引用的值(使用连接?),仅比较不同行的 ArrTime 和 DeptTime,如果差异大于 4 小时, return 多站旅程的 Dept、DeptTime、Arr 和 ArrTime。任何超过 4 小时的时间都被视为该旅程的结束。

我试过使用几个简单的查询,但是我不知道如何计算具有相同 Ref 的不同项目之间的 Datetime 差异,以及如何比较不同行之间的 ArrTime 和 DeptTime。

我在 Whosebug 上发现了这种比较日期时间的方法,但是我在使用它时得到的只是一个语法错误..

DECLARE @date1 DATETIME;
DECLARE @date2 DATETIME;

SET @date1 = '2012-04-01 08:10:16';
SET @date2 = '2012-04-10 11:35:36';

编辑:查询后的最终输出 table 应如下所示:

+------+----------+--------------------+--------+-------------------+
|Ref   |Dept      |DeptTime            |Arr     |ArrTime            |
+------+----------+--------------------+--------+-------------------+
|1     |New York  |2015-02-01 08:00:00 |Dallas  |2015-02-01 13:00:00|
|1     |Dallas    |2015-02-02 11:00:00 |Seattle |2015-02-02 13:00:00|
|2     |London    |2015-02-01 04:00:00 |Berlin  |2015-02-01 16:00:00|
|2     |Berlin    |2015-02-02 18:00:00 |Moscow  |2015-02-02 23:00:00|
+------+----------+--------------------+--------+-------------------+

如有任何帮助,我们将不胜感激!

我会通过创建两个中介 table 来实现此目的以进行报告。

第一个叫做 flight_journey。它根据您的时间要求将每个旅程所在的航班分组。

第二个叫做first_last。它标识每个旅程中的第一个和最后一个航班,因为这就是您想要显示的全部内容。

最后的 select 语句仅使用 first_last table 和自连接来显示您想要的内容。

您可以索引中介 table 以提高性能。

FLIGHT_JOURNEY table:

create table flight_journey as
select z.*, @row_num := if(@prev_value=chk,@row_num+1,1) as journey
from(
select
   f.*, p.arrtime as prev_arr,
   case
when p.depttime is null then 1
when ifnull(hour(timediff(f.depttime, p.arrtime)), 0) <= 4 then
   1
else
   0
end as chk
from
   flights f
left join flights p on f.ref = p.ref
and p.depttime = (select max(z.depttime) from flights z where z.ref = p.ref and z.depttime < f.depttime)
) z,
 (select @row_num := 1) x,
      (select @prev_value := '') y
order by
   z.ref,
   z.depttime;

FIRST_LAST table:

create table first_last as
select
   y.*
from
   (select ref, journey, min(depttime) as min_dept, max(arrtime) as max_arr from flight_journey group by ref, journey) x
join flight_journey y on x.ref = y.ref
and x.journey = y.journey
and (x.min_dept = y.depttime or x.max_arr = y.arrtime);

最终 select 语句:

select
   x.ref,
   x.dept,
   x.depttime,
   y.arr,
   y.arrtime
from
   first_last x
join first_last y on x.ref = y.ref
and x.journey = y.journey
and y.depttime > x.depttime
union all
   select
      x.ref,
      x.dept,
      x.depttime,
      x.arr,
      x.arrtime
   from
      first_last x
   join (select ref, journey from first_last group by ref, journey having count(*) = 1) y on x.ref = y.ref
   and x.journey = y.journey;

Fiddle: http://sqlfiddle.com/#!2/f22b9/2/0

输出:

| REF |     DEPT |                        DEPTTIME |     ARR |                         ARRTIME |
|-----|----------|---------------------------------|---------|---------------------------------|
|   1 | New York | February, 01 2015 08:00:00+0000 |  Dallas | February, 01 2015 13:00:00+0000 |
|   1 |   Dallas | February, 02 2015 11:00:00+0000 | Seattle | February, 02 2015 13:00:00+0000 |
|   2 |   London | February, 01 2015 04:00:00+0000 |  Berlin | February, 01 2015 16:00:00+0000 |
|   2 |   Berlin | February, 02 2015 18:00:00+0000 |  Moscow | February, 02 2015 23:00:00+0000 |