我真的在努力解决这个问题。任何帮助将不胜感激!
表格:
+------+----------+--------------------+--------+-------------------+
|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|
+------+----------+--------------------+--------+-------------------+
此表显示了多站jouneys。当到达和离开之间的停留时间少于4小时时,这应被视为同一行程的一部分。目的地应该是下次出发时间超过四小时的首次到达时间。在这种情况下,我想显示出发城市和出发时间,以及最终到达目的地和到达时间。您可以在此问题的底部看到所需的输出示例。
我认为查询应该做的是选择具有相同ref的值(使用join?),仅比较不同行的ArrTime和DeptTime,如果差异大于4小时,则返回Dept,DeptTime, Arr和ArrTime的多站旅程。超过4小时的任何事情都被视为该旅程的终点。
我尝试过使用几个简单的查询,但是我不知道如何计算具有相同Ref的不同项之间的Datetime差异,以及如何比较不同行之间的ArrTime和DeptTime。
我在StackOverflow上比较日期时发现了这个方法,但是我得到的只是在使用它时出现语法错误。
DECLARE @date1 DATETIME;
DECLARE @date2 DATETIME;
SET @date1 = '2012-04-01 08:10:16';
SET @date2 = '2012-04-10 11:35:36';
编辑:查询后的最终输出表应如下所示:
+------+----------+--------------------+--------+-------------------+
|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|
+------+----------+--------------------+--------+-------------------+
非常感谢任何帮助!
答案 0 :(得分:2)
我会通过创建两个中间表来进行报告。
第一个称为flight_journey
。它根据您的时间要求将每个航班的航班分组。
第二个叫first_last
。它标识了每个旅程中的第一个和最后一个航班,因为您想要展示它。
最终的select语句只使用带有自联接的first_last
表来显示你想要的内容。
您可以索引中间表以提高性能。
FLIGHT_JOURNEY
表:
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
表:
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
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;
小提琴: 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 |