逐行比较间隔

时间:2013-09-12 20:40:23

标签: postgresql date aggregate-functions intervals window-functions

我试图在1年间隔内对日期进行分组,给定标识符,标签是最早的日期,也是最晚的日期。如果在该日期之后的1年间隔内没有日期,那么它将记录它自己的日期作为第一个和最后一个日期。例如,最初的数据是:

id | date 
____________
a  | 1/1/2000
a  | 1/2/2001
a  | 1/6/2000
b  | 1/3/2001
b  | 1/3/2000
b  | 1/3/1999
c  | 1/1/2000
c  | 1/1/2002
c  | 1/1/2003

我想要的输出是:

id  | first_date | last_date
___________________________
a   | 1/1/2000   | 1/2/2001
b   | 1/3/1999   | 1/3/2001
c   | 1/1/2000   | 1/1/2000
c   | 1/1/2002   | 1/1/2003

我一直试图弄清楚这一天,但无法弄明白。我可以为只有2个副本的case id做这个,但不能用于更大的值。任何帮助都会很棒。

3 个答案:

答案 0 :(得分:1)

SELECT id
     , min(min_date) AS min_date
     , max(max_date) AS max_date
     , sum(row_ct)   AS row_ct
FROM  (
   SELECT id, year, min_date, max_date, row_ct
        , year - row_number() OVER (PARTITION BY id ORDER BY year) AS grp
   FROM  (
      SELECT id
           , extract(year FROM the_date)::int AS year
           , min(the_date) AS min_date
           , max(the_date) AS max_date
           , count(*)      AS row_ct
      FROM   tbl
      GROUP  BY id, year
      ) sub1
   ) sub2
GROUP  BY id, grp
ORDER  BY id, grp;

1)在子查询 id, year 中按照(sub1)对所有行进行分组。记录日期的最小值和最大值。我添加了一个行数(row_ct)用于演示。

2)在第二个子查询 row_number() 中减去年份中的sub2。因此,所有连续的行最终都在同一组(grp)中。多年来的差距开始了一个新的群体。

3)在最终SELECT 中,第二次分组,这次是(id, grp)并再次记录最小值,最大值和行数。瞧。产生您正在寻找的结果。

<强> -> SQLfiddle demo.

相关答案:
Return array of years as year ranges
Group by repeating attribute

答案 1 :(得分:0)

select id, min ([date]) first_date, max([date]) last_date
from <yourTbl> group by id

答案 2 :(得分:0)

使用此(SQLFiddle Demo):

SELECT id,
    min(date) AS first_date,
    max(date) AS last_date
FROM mytable
GROUP BY 1
ORDER BY 1