我正在尝试根据提供的月份和年份在窗口中选择第一个和最后一个日期 .
这是示例数据:
F.rates
| id | c_id | date | rate |
---------------------------------
| 1 | 1 | 01-01-1991 | 1 |
| 1 | 1 | 15-01-1991 | 0.5 |
| 1 | 1 | 30-01-1991 | 2 |
.................................
| 1 | 1 | 01-11-2014 | 1 |
| 1 | 1 | 15-11-2014 | 0.5 |
| 1 | 1 | 30-11-2014 | 2 |
这是我提出的pgSQL SELECT:
SELECT c_id, first_value(date) OVER w, last_value(date) OVER w FROM F.rates
WINDOW w AS (PARTITION BY EXTRACT(YEAR FROM date), EXTRACT(MONTH FROM date), c_id
ORDER BY date ASC)
这给了我一个非常接近我想要的结果:
| c_id | first_date | last_date |
----------------------------------
| 1 | 01-01-1991 | 15-01-1991 |
| 1 | 01-01-1991 | 30-01-1991 |
.................................
应该:
| c_id | first_date | last_date |
----------------------------------
| 1 | 01-01-1991 | 30-01-1991 |
.................................
由于某些原因 last_value(date)
返回窗口中的每条记录 . 这给了我一个想法,我喜欢SQL为它迭代的每一行形成一个新窗口,但不是基于YEAR和MONTH的整个表的多个窗口 .
那么任何人都可以善良并解释我是否错了,我如何达到我想要的结果?
有一个原因我没有使用MAX / MIN而不是GROUP BY子句 . 我的下一步是检索我选择的日期的相关费率,例如:
| c_id | first_date | last_date | first_rate | last_rate | avg rate |
-----------------------------------------------------------------------
| 1 | 01-01-1991 | 30-01-1991 | 1 | 2 | 1.1 |
.......................................................................
2 回答
窗口函数不适用于此 . 请改用聚合函数 .
如果您希望将输出分组为单个(或更少)行,则应使用简单聚合(即
GROUP BY
),如果avg_rate
足够:有关PostgreSQL's documentation中窗口函数的更多信息:
EDIT :
如果要折叠(最小/最大聚合)数据并希望收集比
GROUP BY
中列出的列更多的列,则有2个选择:SQL方式
在子查询中选择最小/最大值,然后将其原始行连接起来(但是这样,您必须处理这样的事实,即min / max-ed列通常不唯一):
PostgreSQL的DISTINCT ON
DISTINCT ON通常用于此任务,但高度依赖于排序(一次只能以这种方式搜索1个极值):
您可以将此查询与
F.rates
的其他聚合子查询一起加入,但是这一点(如果您确实需要最小值和最大值,在您的情况下甚至是平均值),SQL兼容的方式更适合 .