Postgresql:使用窗口函数从日期范围中选择MAX值

时间:2017-02-01 23:13:28

标签: sql postgresql

我正在尝试从过去两年内选择最大值

例如,如果我有一个表格如下:

|person_id | pass_or_fail | timestamp|
|----------|--------------|-----------|
|1234      | 1            | 1990-01-01|
|1234      | 0            | 1995-01-01|
|1234      | NULL         | 1995-12-12|
|6789      | 0            | 1990-01-01|
|6789      | 0            | 1991-01-01|
|6789      | 1            | 1995-01-01|
|6789      | 1            | 1996-01-01|
|6789      | 0            | 1997-01-01|
|6789      | NULL         | 1997-03-03|

我希望从我的查询中获得以下内容:

person_id |highest_grade_from_past_two_years | pass_or_fail | timestamp
1234      |1                                 | 1            | 1990-01-01
1234      |0                                 | 0            | 1995-01-01
1234      |0                                 | NULL         | 1995-12-12
6789      |0                                 | 0            | 1990-01-01
6789      |0                                 | 0            | 1991-01-01
6789      |1                                 | 1            | 1995-01-01
6789      |1                                 | 1            | 1996-01-01
6789      |1                                 | 0            | 1997-01-01
6789      |1                                 | NULL         | 1997-03-03

我怎么能写我的窗口函数给我这个结果?

3 个答案:

答案 0 :(得分:0)

我没有看到如何使用窗口函数编写此查询。没有窗口的版本:

SELECT t1.person_id,
       max(t2.pass_or_fail) AS highest_grade_from_past_two_years,
       t1.pass_or_fail,
       t1.timestamp
FROM t AS t1
     JOIN t AS t2 ON (
          t1.person_id = t2.person_id
          AND t2.timestamp < t1.timestamp + '2 year'::interval
          AND t2.timestamp <= t1.timestamp
     )
GROUP BY 1, 3, 4

答案 1 :(得分:0)

加入实际年份 - 1(如果存在)

select p1.person_id, p1.pass_or_fail, p1.timestamp,
       case when coalesce(p1.pass_or_fail,0) > coalesce(p2.pass_or_fail,0) 
            then coalesce(p1.pass_or_fail,0) else coalesce(p2.pass_or_fail,0) end as highest_grade_from_past_two_years
from person p1
     left join person p2
     on p1.person_id = p2.person_id
        and extract(year from p2.timestamp) = extract(year from p1.timestamp) - 1
order by p1.person_id, p1.timestamp

点击此处:http://rextester.com/BNPW52530

答案 2 :(得分:0)

我没有看到使用窗口函数的明显方法。相关的子查询或横向连接可以起作用:

select t.*,
       (select max(t2.pass_or_fail)
        from t t2
        where t2.person_id = t.person_id and
              t2.timestamp <= t.timestamp and
              t2.timestamp >= t.timestamp - interval '2 year'
       ) as highest_grade_from_past_two_years
from t;

我认为窗口函数最接近的是范围规范。但是,Postgres不支持preceding的{​​{1}}规范。