SQL 聚合到最多 3 个日期范围
SQL aggregation into at most 3 date ranges
我需要在 PostgreSQL 中编写一个查询,以根据最多 3 个范围的日期范围从 table 聚合数据。假设我们有以下 table:
CREATE TABLE Purchases (
ID int,
PriceCents int,
PurchaseDate date
);
我想要的是写一个查询到:
1- 取最早的购买日期和最晚的购买日期并将它们分成 3 个不同的日期间隔
2-汇总在计算的时间范围内发生的所有购买的价格并显示
换句话说,假设我们在 table 中有以下数据:
+----+-------------+---------------+
| id | price_cents | purchase_date |
+----+-------------+---------------+
| 1 | 200 | 2020-01-11 |
| 2 | 300 | 2020-01-14 |
| 3 | 100 | 2020-02-02 |
| 4 | 500 | 2020-03-13 |
| 5 | 200 | 2020-07-01 |
| 6 | 300 | 2020-11-17 |
| 7 | 100 | 2021-01-01 |
| 8 | 500 | 2021-01-02 |
+----+-------------+---------------+
在这种情况下,数据介于 2020-01-11
和 2021-01-02
之间
当分成 3 个间隔时,它给我们:
从 2020-01-11
到 2020-05-09
从 2020-05-09
到 2020-09-05
从 2020-09-05
到 2021-01-02
我们希望结果是
+------------+--------------------------+
| total_cost | date_range |
+------------+--------------------------+
| 1100 | 2020-01-11 to 2020-05-09 |
| 200 | 2020-06-10 to 2020-09-05 |
| 900 | 2020-09-06 to 2021-01-02 |
+------------+--------------------------+
如果我提前知道日期范围并且可以将日期“硬编码”到查询中,这个问题就会变得微不足道,但我不知道。
如果您想要大小相等的范围,请使用 ntile()
:
select tile, min(purchase_date), max(purchase_date), sum(price_cents)
from (select p.*,
ntile(3) over (order by purchase_date) as tile
from purchases p
) p
group by tile;
这不是 100% 令人满意,因为范围可以重叠(同一日期可以在两个范围内)。重点是 bin 内的大小相等。所以,如果你想要宽度 bins,那么你可以使用日期算法:
select ceiling((purchase_date - min_pd) / (max_pd - min_pd)) as tile, sum(price_cents)
from (select p.*,
min(purchase_date) over () as min_pd,
max(purchase_date) over () as max_pd
from purchases p
) p
group by tile;
我需要在 PostgreSQL 中编写一个查询,以根据最多 3 个范围的日期范围从 table 聚合数据。假设我们有以下 table:
CREATE TABLE Purchases (
ID int,
PriceCents int,
PurchaseDate date
);
我想要的是写一个查询到:
1- 取最早的购买日期和最晚的购买日期并将它们分成 3 个不同的日期间隔
2-汇总在计算的时间范围内发生的所有购买的价格并显示
换句话说,假设我们在 table 中有以下数据:
+----+-------------+---------------+
| id | price_cents | purchase_date |
+----+-------------+---------------+
| 1 | 200 | 2020-01-11 |
| 2 | 300 | 2020-01-14 |
| 3 | 100 | 2020-02-02 |
| 4 | 500 | 2020-03-13 |
| 5 | 200 | 2020-07-01 |
| 6 | 300 | 2020-11-17 |
| 7 | 100 | 2021-01-01 |
| 8 | 500 | 2021-01-02 |
+----+-------------+---------------+
在这种情况下,数据介于 2020-01-11
和 2021-01-02
之间
当分成 3 个间隔时,它给我们:
从 2020-01-11
到 2020-05-09
从 2020-05-09
到 2020-09-05
从 2020-09-05
到 2021-01-02
我们希望结果是
+------------+--------------------------+
| total_cost | date_range |
+------------+--------------------------+
| 1100 | 2020-01-11 to 2020-05-09 |
| 200 | 2020-06-10 to 2020-09-05 |
| 900 | 2020-09-06 to 2021-01-02 |
+------------+--------------------------+
如果我提前知道日期范围并且可以将日期“硬编码”到查询中,这个问题就会变得微不足道,但我不知道。
如果您想要大小相等的范围,请使用 ntile()
:
select tile, min(purchase_date), max(purchase_date), sum(price_cents)
from (select p.*,
ntile(3) over (order by purchase_date) as tile
from purchases p
) p
group by tile;
这不是 100% 令人满意,因为范围可以重叠(同一日期可以在两个范围内)。重点是 bin 内的大小相等。所以,如果你想要宽度 bins,那么你可以使用日期算法:
select ceiling((purchase_date - min_pd) / (max_pd - min_pd)) as tile, sum(price_cents)
from (select p.*,
min(purchase_date) over () as min_pd,
max(purchase_date) over () as max_pd
from purchases p
) p
group by tile;