获取postgresql中其他分区的最后一个值

yquaqz18  于 2023-01-30  发布在  PostgreSQL
关注(0)|答案(3)|浏览(152)

我得到了这个SCD表:
| 开始日期|结束日期|分区|
| - ------|- ------|- ------|
| 2022年3月8日15:35:09.856|2022年3月9日14时57分36.610秒|1个|
| 2022年3月9日14时57分36.610秒|2022年5月18日13时26分31.195秒|第二章|
| 2022年5月18日13时26分31.195秒|2022年8月2日10时12分02秒441|第二章|
| 2022年8月2日10时12分02秒441|2022年9月1日11时10分01秒019|第二章|
| 2022年9月1日11时10分01秒019|2022年9月1日11时10分20秒777|1个|
| 2022年9月1日11时10分20秒777|2022年9月1日11时21分26.526秒|1个|
我想知道每个分区的start_date和end_date在另一个分区的最后一个值(只有两个)。对于给定的表:
| 开始日期|结束日期|分区|最大开始日期|最大结束日期|
| - ------|- ------|- ------|- ------|- ------|
| 2022年3月8日15:35:09.856|2022年3月9日14时57分36.610秒|1个|零|零|
| 2022年3月9日14时57分36.610秒|2022年5月18日13时26分31.195秒|第二章|2022年3月8日15:35:09.856|2022年3月9日14时57分36.610秒|
| 2022年5月18日13时26分31.195秒|2022年8月2日10时12分02秒441|第二章|2022年3月8日15:35:09.856|2022年3月9日14时57分36.610秒|
| 2022年8月2日10时12分02秒441|2022年9月1日11时10分01秒019|第二章|2022年3月8日15:35:09.856|2022年3月9日14时57分36.610秒|
| 2022年9月1日11时10分01秒019|2022年9月1日11时10分20秒777|1个|2022年8月2日10时12分02秒441|2022年9月1日11时10分01秒019|
| 2022年9月1日11时10分20秒777|2022年9月1日11时21分26.526秒|1个|2022年8月2日10时12分02秒441|2022年9月1日11时10分01秒019|
我尝试了一些last_value窗口函数,但没有成功。,last_value(start_date)OVER(按分区='1'按start_date asc排序)as last_start_date_partition,last_value(end_date)OVER(按分区='1'按end_date asc排序)as last_end_date_partition是否有任何选项可以将条件注入窗口函数并使其按此方式运行?

fnx2tebb

fnx2tebb1#

使用dense_rank

with cte as (
   select (select sum((s1.start_date < s.start_date and s1.partition != s.partition)::int) 
     from scd s1) r, s.* 
   from scd s
),
n_part as (
   select dense_rank() over (order by c.r) dr, c.* from cte c
)
select np.start_date, np.end_date, np.partition, max(np1.start_date), max(np1.end_date) 
from n_part np left join n_part np1 on np1.dr = np.dr - 1
group by np.start_date, np.end_date, np.partition
order by np.start_date, np.end_date

See fiddle .

11dmarpk

11dmarpk2#

使用窗口函数和gaps-and-islandish方法:

SELECT start_date,
       end_date,
       PARTITION,
       max(start_date) OVER (ORDER BY grp RANGE UNBOUNDED PRECEDING EXCLUDE GROUP) max_start_date, -- use max value without current group
       max(end_date) OVER (ORDER BY grp RANGE UNBOUNDED PRECEDING EXCLUDE GROUP) max_end_date -- use max value without current group
FROM
  (SELECT start_date,
          end_date,
          PARTITION,
          sum(lag) OVER (ORDER BY end_date) AS grp -- use cumulative sum to create a group
   FROM
     (SELECT *,
             CASE
                 WHEN lag(PARTITION) OVER (ORDER BY end_date) != PARTITION THEN 1
                 ELSE 0
             END lag -- use lag to determine if the partition has changed
      FROM mytable) t) tt

Fiddle

yacmzcpb

yacmzcpb3#

您可以执行自左连接和聚合,如下所示:

select T.start_date, T.end_date, T.partition_,
       max(D.start_date) max_start_date,
       max(D.end_date) max_end_date
from SCD T left join SCD D
on T.start_date > D.start_date and 
   T.partition_ <> D.partition_
group by T.start_date, T.end_date, T.partition_
order by T.start_date

See demo

相关问题