In a trip there are several stops, (a stop = an adress whereone or multiple orders are loaded, or delivered), in a specific order. For example:
Trip A
Trip_order Action Place Ordernumber
10 Load Paris 394798
20 Load Milan 657748
30 UnLoad Athens 657748
40 Unload Thessaloniki 394798
50 Load Thessaloniki 10142
60 Load Thessaloniki 6577
70 Unload Athens 6577
80 Unload Athens 10412
90 Load Thessaloniki 975147
100 Unload Paris 975147
I want to see the specific stops, in order of the trip:
Load Paris
Load Milan
Unload Athens
Unload Thessaloniki
Load Thessaloniki
Unload Athens
Load Thessaloniki
Unload Paris
I did look at This, but if I do that, I only get the unload Athens, unload Thessaloniki and Load Thessaloniki once.
How do I solve this?
EDIT: 11:11 (UTC +01:00) To be more specific: these are the tables which present this information:
Trips
Trip_ID
100001
100002
100003
....
Actions
Trip_ID Action MatNr RoOr RoVlg OrderID
100001 1 10 10 1 394798
100001 1 10 20 1 657748
100001 1 10 30 1 657748
100001 1 10 40 1 394798
100001 1 10 50 1 10142
100001 1 10 60 1 6577
100001 1 10 70 1 6577
100001 1 10 80 1 10412
100001 1 10 90 1 975147
100001 1 10 100 1 975147
(Action: 1=load, 4=unload) The combination of MatNr, RoOr and RoVlg is the order of the Trip.
Orders
OrderID LoadingPlace UnloadingPlace
6577 Thessaloniki Athens
10142 Thessaloniki Athens
394798 Paris Thessaloniki
657748 Milan Athens
975147 Thessaloniki Paris
The SELECT DISTINCT statement is used to return only distinct (different) values. Inside a table, a column often contains many duplicate values; and sometimes you only want to list the different (distinct) values.
The SQL SELECT DISTINCT Statement The DISTINCT clause is used in a SELECT statement to remove duplicates from the result set of the query.
To get unique or distinct values of a column in MySQL Table, use the following SQL Query. SELECT DISTINCT(column_name) FROM your_table_name; You can select distinct values for one or more columns. The column names has to be separated with comma.
Try this one. No variables, nothing especially fancy:
select a1.action, a1.place
from trip_a a1
left join trip_a a2
on a2.trip_order =
(select min(trip_order)
from trip_a a3
where trip_order > a1.trip_order)
where a1.action != a2.action or a1.place != a2.place or a2.place is null
Demo here: http://sqlfiddle.com/#!9/4b6dc/13
Hopefully it works on whatever sql you're using, it should, so long as subqueries are supported.
Tt simply finds the next highest trip_id
, and joins to it, or joins to null
if there is no higher trip_order
. It then selects only the rows where either the place
, the action
, or both are different, or if there is no place in the joined table (a2.place is null
).
edited after criteria changed completely
If you want to get the same results, built entirely from your base tables, you can do this:
select
case when a.action = 1 then 'load' when a.action = 0 then 'unload' end as action,
case when a.action = 1 then o.loadingplace when a.action = 0 then o.unloadingplace end as place
from trips t
inner join actions a
on t.trip_id = a.trip_id
inner join orders o
on a.orderid = o.orderid
left join actions a2
on a2.roor =
(select min(roor)
from actions a3
where a3.roor > a.roor)
left join orders o2
on a2.orderid = o2.orderid
where a.action != a2.action
or a2.action is null
or
case when a.action = 1 then o.loadingplace != o2.loadingplace
when a.action = 0 then o.unloadingplace != o2.unloadingplace
end
order by a.roor asc
And here's an updated fiddle: http://sqlfiddle.com/#!9/fdf9c/14
You don't need and you don't want to use distinct
for that because we can see in your example that several destinations occur multiple times. What you want: filter out records that match the preceding record in terms of action and place.
This could look something like this:
SELECT *
FROM Trips t1 LEFT JOIN Trips t2 ON t1.Trip_Order = t2.Trip_Order - 10
WHERE t1.Action <> t2.Action OR t1.Place <> t2.Place)
In SQL server, you can get difference of ROW_NUMBER()
based trip_order
and action,place
on and try something like this.
You can use it as a reference to create a similar query in USQL.
Sample Data
DECLARE @Trip TABLE (Trip_order INT, Action VARCHAR(10), Place VARCHAR(50),Ordernumber INT)
INSERT INTO @Trip VALUES
(10 ,'Load', 'Paris', 394798),
(20 ,'Load', 'Milan', 657748),
(30 ,'UnLoad', 'Athens', 657748),
(40 ,'UnLoad', 'Thessaloniki', 394798),
(50 ,'Load', 'Thessaloniki', 10142),
(60 ,'Load', 'Thessaloniki', 6577),
(70 ,'UnLoad', 'Athens', 6577),
(80 ,'UnLoad', 'Athens', 10412),
(90 ,'Load', 'Thessaloniki', 975147),
(100 ,'UnLoad', 'Paris', 975147);
Query
SELECT action,place FROM
(
SELECT *,ROW_NUMBER()OVER(ORDER BY trip_order) - ROW_NUMBER()OVER(ORDER BY action,place) n
FROM @trip
)t
GROUP BY n,action,place
ORDER BY MIN(trip_order)
Try this:
Will work in MySQL:::
SELECT IF(@temp=@temp:=A.TripName, @rank, @rank:=@rank+1) AS rank, A.TripName
FROM (SELECT CONCAT(A.Action, A.Place) AS TripName
FROM TripA A
) A, (SELECT @temp:=0, @rank:=0) AS B
GROUP BY rank
SELECT s.*
FROM stops s LEFT JOIN stops prev ON
( prev.Trip_order < s.Trip_order
AND NOT EXISTS ( SELECT 'a'
FROM stops prev2
WHERE prev2.Trip_order < s.Trip_order
AND prev2.Trip_order > prev.Trip_order
)
)
WHERE s.Action <> COALESCE(prev.Action, '')
OR s.Place <> COALESCE(prev.Place, '')
ORDER BY s.Trip_order
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With