Reputation: 3006
I have three tables
Drivers
driver_id | driver_name |driver_number
----------------------------------------
1 | Driver 1 | 99999
2 | Driver 2 | 88888
Each Driver has shifts
shift_id | start_time | end_time | driver_id
-----------------------------------------------------------------
4 |2015-04-02 10:09:00 |(NULL) | 1
3 |2015-04-02 09:19:00 |(NULL) | 2
2 |2015-04-02 11:09:00 |2015-04-02 19:09:00 | 1
1 |2015-04-02 10:09:00 |2015-04-02 20:09:00 | 2
And during each shift, driver may or may NOT do multiple trips
trip_id | start_time | end_time | shift_id
-----------------------------------------------------------------
12 |2015-04-02 10:09:00 |(NULL) | 4
11 |2015-04-02 09:19:00 |(NULL) | 4
10 |2015-04-02 11:09:00 |2015-04-02 19:09:00 | 3
9 |2015-04-02 10:09:00 |2015-04-02 20:09:00 | 2
8 |2015-04-02 10:09:00 |(NULL) | 4
7 |2015-04-02 09:19:00 |(NULL) | 4
6 |2015-04-02 11:09:00 |2015-04-02 19:09:00 | 3
5 |2015-04-02 10:09:00 |2015-04-02 20:09:00 | 4
4 |2015-04-02 10:09:00 |(NULL) | 4
3 |2015-04-02 09:19:00 |(NULL) | 4
2 |2015-04-02 11:09:00 |2015-04-02 19:09:00 | 2
1 |2015-04-02 10:09:00 |2015-04-02 20:09:00 | 1
I want to get a query where I get the recent most trip along with driver details, in the open shifts (end time null).
All that I've been trying has failed.
I understand the query should be something like this:
select * from
drivers
inner join shifts on shifts.driver_id = drivers.driver_id
left join (some inner query on trips table) as trip
on shifts.shift_id = trip.trip_id
where shifts.end_time is null;
Please help me with a query. The expected result is something like:
driver_id | driver_name | shift_id | shift_start_time | recent_trip_id | recent_trip_start_time
1 | Driver 1 | 4 | 2015-05-02 10:09:00 | 12 | 2015-04-02 10:09:00
2 | Driver 2 | 3 | 2015-05-02 11:09:00 | 10 | 2015-04-02 11:09:00
Upvotes: 4
Views: 387
Reputation: 16325
This ought to do what you're looking for.
SELECT s.*, d.*, t.*
FROM shifts AS s
INNER JOIN drivers AS d
ON s.driver_id = d.driver_id
INNER JOIN (
SELECT MAX(t.trip_id) AS trip_id
FROM trips AS t
INNER JOIN shifts AS s
ON t.shift_id = s.shift_id
AND s.end_time IS NULL
GROUP BY s.shift_id) AS mt
INNER JOIN trips AS t
ON s.shift_id = t.shift_id
AND t.trip_id = mt.trip_id;
SQL Fiddle added and column names fixed: http://sqlfiddle.com/#!9/faeca/5
Upvotes: 1
Reputation: 72175
You can use variables to determine the most recent trip within each shift partition:
SELECT d.driver_id, d.driver_name, s.shift_id, s.start_time AS shift_start_time,
t.trip_id AS recent_trip_id, t.start_time AS recent_trip_start_time
FROM drivers AS d
INNER JOIN shifts AS s ON s.driver_id = d.driver_id
INNER JOIN (
SELECT trip_id, start_time,
@row_number:= CASE WHEN @sid = shift_id THEN @row_number+1
ELSE 1
END AS row_number,
@sid:=shift_id AS shift_id
FROM trips, (SELECT @sid:=0,@row_number:=0) as vars
ORDER BY shift_id, trip_id DESC ) t ON t.shift_id = s.shift_id AND t.row_number = 1
WHERE s.end_time IS NULL
Predicate t.row_number = 1
effectively selects the most recent trip per shift. The rest of the query are just simple JOIN
clauses that gather together driver and (open) shift data.
Upvotes: 1