将具有多个属性的行转换为每行具有一个属性的行

Convert rows with multiple attributes into rows with one attribute per row

我有一个 table 格式如下:

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 

但是,我需要一个 returns 类似这样的查询(最好不定义其他函数)

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

联合所有:

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

参见demo
结果:

| 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 |

编辑。
使用 LATERAL ... VALUES 可能更有效(虽然不简单):

select t.id, v.*
from tablename t, 
  lateral (values
    ('Arrival', t.Arrival),
    ('Departure', t.Departure),
    ('Expected Return', t."Expected Return")
   ) v (Action, Date);

参见demo