从间隔中拆分值并按 isoweek 分组 - Postgresql
Split values from an interval and group by isoweek - Postgresql
我想根据日期间隔将 "distribute" 或 "split" 小时从单个任务转换为 iso 周。但是我不知道如何在 Postgresql 中执行此操作。
CREATE TABLE task
(id int4, start date, stop date, hr int4);
INSERT INTO task
(id, start, stop, hr)
VALUES
(1, '2017-01-01','2017-01-31', 80),
(2, '2017-01-01','2017-02-28', 120);
这 2 个任务的预期输出应该是这样的:
The 80 hr of task 1 should be distributed into 5 weeks
201701 16 hr
201702 16 hr
201703 16 hr
201704 16 hr
201705 16 hr
The 120 hr of task 2 should be distributed into 9 weeks
201701 13,3 hr
201702 13,3 hr
201703 13,3 hr
201704 13,3 hr
201705 13,3 hr
201706 13,3 hr
201707 13,3 hr
201708 13,3 hr
201709 13,6 hr
此估计为粗略估计,可能与实际情况不同。
我可以想到三个步骤(但想不通):
- 估计每个任务的周数
- 小时数除以周数
- 按 iso 周对结果进行分组
SELECT id,
yr * 100 + w AS week,
hr::double precision / (stop_week - start_week + 1) AS hrs_per_week
FROM (
SELECT id,
extract(year from start)::integer AS yr,
extract(week from start)::integer AS start_week,
extract(week from stop)::integer AS stop_week,
hr
FROM task) sub,
generate_series(start_week, stop_week) weeks(w)
ORDER BY 1, 2;
在 sub
查询中收集了每一行的一些基本数据,generate_series()
set-returning 函数将其转换为一组行,每周一行。然后主查询计算每个任务每周的小时数。
请注意,这不适用于多年。如果需要,则必须扩展 sub
查询以获取开始和结束年份并计算跨年的周数。
根据帕特里克的回答,我找到了这个解决方案:
SELECT id,to_char(iso, 'iyyy-iw'),(hr/weeks)::numeric (5,2) as hr_week
FROM (SELECT id,hr,generate_series(start,stop,interval '1 week') as iso,
(stop - start)/7 as weeks FROM task) as sub
http://sqlfiddle.com/#!15/93ee1/78
非常感谢!
我想根据日期间隔将 "distribute" 或 "split" 小时从单个任务转换为 iso 周。但是我不知道如何在 Postgresql 中执行此操作。
CREATE TABLE task
(id int4, start date, stop date, hr int4);
INSERT INTO task
(id, start, stop, hr)
VALUES
(1, '2017-01-01','2017-01-31', 80),
(2, '2017-01-01','2017-02-28', 120);
这 2 个任务的预期输出应该是这样的:
The 80 hr of task 1 should be distributed into 5 weeks
201701 16 hr
201702 16 hr
201703 16 hr
201704 16 hr
201705 16 hr
The 120 hr of task 2 should be distributed into 9 weeks
201701 13,3 hr
201702 13,3 hr
201703 13,3 hr
201704 13,3 hr
201705 13,3 hr
201706 13,3 hr
201707 13,3 hr
201708 13,3 hr
201709 13,6 hr
此估计为粗略估计,可能与实际情况不同。
我可以想到三个步骤(但想不通):
- 估计每个任务的周数
- 小时数除以周数
- 按 iso 周对结果进行分组
SELECT id,
yr * 100 + w AS week,
hr::double precision / (stop_week - start_week + 1) AS hrs_per_week
FROM (
SELECT id,
extract(year from start)::integer AS yr,
extract(week from start)::integer AS start_week,
extract(week from stop)::integer AS stop_week,
hr
FROM task) sub,
generate_series(start_week, stop_week) weeks(w)
ORDER BY 1, 2;
在 sub
查询中收集了每一行的一些基本数据,generate_series()
set-returning 函数将其转换为一组行,每周一行。然后主查询计算每个任务每周的小时数。
请注意,这不适用于多年。如果需要,则必须扩展 sub
查询以获取开始和结束年份并计算跨年的周数。
根据帕特里克的回答,我找到了这个解决方案:
SELECT id,to_char(iso, 'iyyy-iw'),(hr/weeks)::numeric (5,2) as hr_week
FROM (SELECT id,hr,generate_series(start,stop,interval '1 week') as iso,
(stop - start)/7 as weeks FROM task) as sub
http://sqlfiddle.com/#!15/93ee1/78
非常感谢!