我需要对Postgres数据库表进行转换,但我不知道从哪里开始。 下表如下:
| Customer Code | Activity | Start Date |
|:---------------:|:--------:|:----------:|
| 100 | A | 01/05/2017 |
| 100 | A | 19/07/2017 |
| 100 | B | 18/09/2017 |
| 100 | C | 07/12/2017 |
| 101 | A | 11/02/2018 |
| 101 | B | 02/04/2018 |
| 101 | B | 14/06/2018 |
| 100 | A | 13/07/2018 |
| 100 | B | 14/08/2018 |
客户可以始终按该顺序执行活动 A、B 和 C。 为了进行活动B,他/她必须进行活动A。要执行C,他/她必须执行活动A,然后执行B。 一个活动或周期可以由同一客户执行多次。
我需要以这种方式重新组织表格,放置每个步骤的开头和结尾:
| Customer Code | Activity | Start Date | End Date |
|:---------------:|:--------:|:----------:|:----------:|
| 100 | A | 01/05/2017 | 18/09/2017 |
| 100 | B | 18/09/2017 | 07/12/2017 |
| 100 | C | 07/12/2017 | 13/07/2018 |
| 101 | A | 11/02/2018 | 02/04/2018 |
| 101 | B | 02/04/2018 | |
| 100 | A | 13/07/2018 | 14/08/2018 |
| 100 | B | 14/08/2018 | |
这是解决这个缺口和孤岛问题的方法:
select
customer_code,
activity,
start_date,
case when (activity, lead(activity) over(partition by customer_code order by start_date))
in (('A', 'B'), ('B', 'C'), ('C', 'A'))
then lead(start_date) over(partition by customer_code order by start_date)
end end_date
from (
select
t.*,
lead(activity) over(partition by customer_code order by start_date) lead_activity
from mytable t
) t
where activity is distinct from lead_activity
查询首先删除具有相同customer_code
和activity
的连续行。然后,当activty
按顺序排列时,我们使用条件逻辑引入下一行的start_date
。
DB小提琴上的演示:
customer_code | 活动 | start_date | end_date ------------: |:------- |:--------- |:--------- 100 |一 |2017-07-19 |2017-09-18 100 |乙 |2017-09-18 |2017-12-07 100 |C |2017-12-07 |2018-07-13 100 |一 |2018-07-13 |2018-08-14 100 |乙 |2018-08-14 |空101 |一 |2018-02-11 |2018-06-14 101 |乙 |2018-06-14 |零