SQL查询,返回基于日期条目的行数

时间:2016-07-30 04:54:30

标签: sql postgresql

我有一个postgres数据库表,跟踪季度事件,季度事件日期和成本。 每个活动至少有5个季度的信息,有些活动有8个或更多的季度。

样本表

EventA | 2013-01-01 | 500 EventA | 2013-04-01 | 600 EventA | 2013-07-01 | 700 EventA | 2013-10-01 | 700 EventA | 2014-01-01 | 750 EventB | 2013-01-01 | 400 EventB | 2013-04-01 | 500 EventB | 2013-07-01 | 600 EventB | 2013-10-01 | 600 EventB | 2014-01-01 | 575 EventB | 2014-04-01 | 700 EventB | 2014-07-01 | 750 EventB | 2014-10-01 | 800 EventB | 2015-01-01 | 800 EventB | 2015-04-01 | 840

我希望能够通过查询执行以下操作。如果一个事件有6行或更少的行,则返回第一季度的行和最后一行。如果赛事有7个或更多赛季,则返回最后一个季度(最新日期)和第6个季度。即,如果一个活动有3年的信息,12个季度,我希望看到第12季度和第6季度。

我知道如何使用窗口函数按事件返回四分之一计数,并使用子查询根据事件的季度数得到结果,即小于6或大于10。我被卡住了。我认为我需要使用这些结果集并将它们联合起来以返回我之后的行,但不知道如何执行此操作。

因此从上面的示例返回的样本数据将是

EventA | 2013-01-01 | 500 EventA | 2014-01-01 | 750 EventB | 2013-10-01 | 600 EventB | 2015-04-10 | 840

提前致谢

1 个答案:

答案 0 :(得分:1)

示例数据:

create table events (event text, quarter date, cost integer);
insert into events values

('EventA', '2013-01-01', 500),
('EventA', '2013-04-01', 600),
('EventA', '2013-07-01', 700),
('EventA', '2013-10-01', 700),
('EventA', '2014-01-01', 750),
('EventB', '2013-01-01', 400),
('EventB', '2013-04-01', 500),
('EventB', '2013-07-01', 600),
('EventB', '2013-10-01', 600),
('EventB', '2014-01-01', 575),
('EventB', '2014-04-01', 700),
('EventB', '2014-07-01', 750),
('EventB', '2014-10-01', 800),
('EventB', '2015-01-01', 800),
('EventB', '2015-04-01', 840);

选择:
- 按降序排列的行号和
- 事件

中分区中的多个行

并选择:
- 分区中的第一行和
- 第七行或最后一行取决于哪个数字较少。

select event, quarter, cost
from (
    select 
        *, 
        row_number() over (partition by event order by quarter desc) rn,
        count(*) over (partition by event) maxn
    from events
    ) s
where rn = 1 or rn = least(maxn, 7)
order by 1, 2;

 event  |  quarter   | cost 
--------+------------+------
 EventA | 2013-01-01 |  500
 EventA | 2014-01-01 |  750
 EventB | 2013-10-01 |  600
 EventB | 2015-04-01 |  840
(4 rows)