我试图在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做这个,但不能用于更大的值。任何帮助都会很棒。
答案 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