I have a table in the following form:
Id | Arrival | Departure | Expected Return
-------------------------------------------------
1 | 2019/8/2 | 2019/8/10 | 2019/8/15
2 | 2019/8/1 | 2019/8/15 | 2019/8/22
3 | 2019/8/2 | 2019/8/16 | 2019/8/21
however, I would need a query that returns something like this (ideally without defining additional functions)
Id | Action | Date
--------------------------------------
1 | Arrival | 2019/8/2
1 | Departure | 2019/8/10
1 | Expected Return | 2019/8/15
2 | Arrival | 2019/8/1
2 | Departure | 2019/8/15
2 | Expected Return | 2019/8/22
3 | Arrival | 2019/8/2
3 | Departure | 2019/8/16
3 | Expected Return | 2019/8/21
With UNION ALL:
select Id, 'Arrival' "Action", Arrival Date from tablename
union all
select Id, 'Departure' "Action", Departure Date from tablename
union all
select Id, 'Expected Return' "Action", "Expected Return" Date from tablename
order by Id, Date
See the demo.
Results:
| id | Action | date |
| --- | --------------- | -----------|
| 1 | Arrival | 2019-08-02 |
| 1 | Departure | 2019-08-10 |
| 1 | Expected Return | 2019-08-15 |
| 2 | Arrival | 2019-08-01 |
| 2 | Departure | 2019-08-15 |
| 2 | Expected Return | 2019-08-22 |
| 3 | Arrival | 2019-08-02 |
| 3 | Departure | 2019-08-16 |
| 3 | Expected Return | 2019-08-21 |
Edit.
Using LATERAL
... VALUES
could be more efficient (although not simpler):
select t.id, v.*
from tablename t,
lateral (values
('Arrival', t.Arrival),
('Departure', t.Departure),
('Expected Return', t."Expected Return")
) v (Action, Date);
See the demo.