Sql 日期窗口函数

Sql 日期窗口函数,sql,postgresql,Sql,Postgresql,不知道如何解决问题。可能是你能指出正确的方向或给出链接。 我有一张桌子: id Date 23 01.01.2020 23 03.01.2020 23 04.01.2020 56 07.01.2020 56 08.01.2020 87 11.01.2020 23 12.01.2020 23 18.01.2020 我想聚合数据id、日期和最小值,并添加如下新列: id Date_min Da

不知道如何解决问题。可能是你能指出正确的方向或给出链接。 我有一张桌子:

    id  Date
    23  01.01.2020
    23  03.01.2020
    23  04.01.2020
    56  07.01.2020
    56  08.01.2020
    87  11.01.2020
    23  12.01.2020
    23  18.01.2020
我想聚合数据id、日期和最小值,并添加如下新列:

id  Date_min        Date_new
23  01.01.2020  07.01.2020
56  07.01.2020  11.01.2020
87  11.01.2020  12.01.2020
23  12.01.2020  18.01.2020

在Data_new列中,我希望看到下一个用户的第一个日期。如果没有下一个用户,添加用户的最大日期将为您提供下一个日期,但我们也有轻微的卡滞问题,您的ID会重复,因此我们需要一些东西使第二个23与第一个23不同。为此,我想我们可以建立一个计数器,每当ID发生变化时,计数器都会滴答作响:

with a as(        
    select '23' as id, '01.01.2020' as "date" union all
    select '23' as id, '03.01.2020' as "date" union all
    select '23' as id, '04.01.2020' as "date" union all
    select '56' as id, '07.01.2020' as "date" union all
    select '56' as id, '08.01.2020' as "date" union all
    select '87' as id, '11.01.2020' as "date" union all
    select '23' as id, '12.01.2020' as "date" union all
    select '23' as id, '18.01.2020' as "date"
), b as (
  SELECT *, LAG(id) OVER(ORDER BY "date") as last_id FROM a
), c AS(
  SELECT *, 
  LEAD("date") OVER(ORDER BY "date") as next_date, 
  SUM(CASE WHEN last_id <> id THEN 1 ELSE 0 END) OVER(ORDER BY "date" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) id_ctr
  FROM b
)

SELECT id, MIN("date"), MAX(next_date)
FROM c
GROUP BY id, id_ctr
我没有一个PG实例来测试它,但它在SQLS中工作,我非常确定PG支持SQLS所做的一切——这里没有任何特定于SQLS的东西

a取代了您的表-您可以将其从查询中删除,只需将b作为select直接插入d a即可。。。从你的表名开始 b计算上一个ID;我们将使用它来检测id是否在当前行和上一行之间发生了更改。如果它改变了,我们将把它设为1,否则设为0。当这些被汇总为一个运行总数时,它实际上意味着每次ID改变时计数器都会上升,因此我们可以根据此计数器以及ID进行分组,以将我们的两个23分开。我们需要单独执行此操作,因为窗口函数不能嵌套 c取最后一个_id并计算运行总数。它还使用一个简单的窗口函数来执行下一个_日期,该函数从以下按日期排序的行中提取日期。无界的前一行和当前行之间的行在技术上是不必要的,因为这是ORDERBY上求和的默认操作,但我发现显式有助于记录/更改(如果需要) 然后只需选择id、min date和max next_date,但也要在其中加入计数器,以便将23分为多个列-允许按比所选列更多的列分组,但不能按相反的方式分组
这是一种特别简单的缺口和孤岛问题

您可以简单地使用lag来确定每一组行的第一行,然后使用lead来获取新的日期:

他是一把小提琴

三个窗口函数,没有聚合:这应该是解决此问题的最快方法

select id, date as date_min,
       lead(date, 1, max_date) over (order by date) as date_max
from (select t.*,
             lag(id) over (order by date) as prev_id,
             max(date) over () as max_date
      from t
     ) t
where prev_id is null or prev_id <> id;