Nice puzzle ;-)
ct devendrap(TicketNo int,
LegNo int,
Place varchar (20),
TS Timestamp(0)
);
ins devendrap(1, 1,'New York', current_timestamp(0));
ins devendrap(1, 2,'Detroit', current_timestamp(0) + interval '01' hour);
ins devendrap(1, 3,'Chicago', current_timestamp(0) + interval '02' hour);
ins devendrap(1, 4,'Florida', current_timestamp(0) + interval '03' hour);
ins devendrap(2, 1,'New York', current_timestamp(0));
ins devendrap(2, 2,'Chicago', current_timestamp(0) + interval '01' hour);
ins devendrap(2, 3,'Detroit', current_timestamp(0) + interval '02' hour);
ins devendrap(2, 4,'Florida', current_timestamp(0) + interval '03' hour);
ins devendrap(3, 1,'New York', current_timestamp(0));
ins devendrap(3, 2,'Detroit', current_timestamp(0) + interval '01' hour);
ins devendrap(3, 3,'Florida', current_timestamp(0) + interval '02' hour);
ins devendrap(3, 4,'Chicago', current_timestamp(0) + interval '03' hour);
ins devendrap(4, 1,'New York', current_timestamp(0));
ins devendrap(4, 2,'Florida', current_timestamp(0) + interval '01' hour);
ins devendrap(4, 3,'Chicago', current_timestamp(0) + interval '02' hour);
Non stop flights only or Detroit-Chicago via New York also?
Do you have a leg number in your table?
Then it's quite easy:
select
d.ticketno,
d.ts as Depart,
a.ts as Arrival,
(Arrival - Depart) hour to minute as Diff
from
devendrap d, devendrap a
where d.ticketNo = a.ticketNo
and d.place = 'Detroit'
and a.place = 'Chicago'
and
--non stop flights only?
a.LegNo = d.LegNo + 1;
--or flights via ...?
Arrival > Depart;
Instead of a self join you could also use an aggregation:
select
ticketno,
min(case when Place = 'Detroit' then ts end) as Depart,
min(case when Place = 'Chicago' then ts end) as Arrival,
(Arrival - Depart) hour to minute as Diff
from devendrap
group by ticketno
having
--non stop flights only?
min(case when Place = 'Chicago' then legno end) -
min(case when Place = 'Detroit' then legno end) = 1;
--or flights via ...?
Arrival > Depart;
If you need non stop flights only and don't have a leg number, use an OLAP function to create it:
select
ticketno,
min(case when Place = 'Detroit' then ts end) as Depart,
min(case when Place = 'Chicago' then ts end) as Arrival,
(Arrival - Depart) hour to minute as Diff
from
(
select
ticketno,
place,
ts,
rank() over (partition by ticketno order by ts) as LegNo
from devendrap
) dt
group by ticketno
having
min(case when Place = 'Chicago' then legno end) -
min(case when Place = 'Detroit' then legno end) = 1;
Dieter