Sql 使用条件获取表的前N行
这是我们处理的一些调度数据的人为示例 这个想法是天真地问这个问题 假设一个项目有N个剩余的非计划时间,负责人计算在该项目上工作的人数,并假设每个工人将工作8天;本项目需要在最后一个计划日之后的哪些非周末日 我有一个简化的dim_dates表:Sql 使用条件获取表的前N行,sql,postgresql,Sql,Postgresql,这是我们处理的一些调度数据的人为示例 这个想法是天真地问这个问题 假设一个项目有N个剩余的非计划时间,负责人计算在该项目上工作的人数,并假设每个工人将工作8天;本项目需要在最后一个计划日之后的哪些非周末日 我有一个简化的dim_dates表: CREATE TABLE dim_dates ( date_actual DATE NOT NULL, is_weekend BOOLEAN NOT NULL ); 以及项目表: CREATE TABLE projects ( id SERI
CREATE TABLE dim_dates (
date_actual DATE NOT NULL,
is_weekend BOOLEAN NOT NULL
);
以及项目表:
CREATE TABLE projects (
id SERIAL PRIMARY KEY NOT NULL,
last_scheduled_date DATE NOT NULL,
remaining_hours_required INT NOT NULL,
head_count INTEGER NOT NULL
);
因此,考虑到这个项目:
INSERT INTO projects (last_scheduled_date, remaining_hours_required, head_count)
VALUES ('2018-01-04', 21, 1);
通过计算CEILREMAIN_hours_required::decimal/8*head_count,我们最终需要3天的工作。2018-01-04的日期是星期四,因此我们应该在下一个星期五、星期一和星期二结束
要获得以下非周末日,我们可以轻松加入dim_dates:
SELECT p.*, d.*
FROM projects p
INNER JOIN dim_dates d ON (
d.date_actual > p.last_scheduled_date
AND
d.is_weekend IS FALSE
);
这将给我们提供以下不是周末的日期。我的难题是如何将此集合筛选为3行
因此,必要的任务描述是:
计算完成项目所需的剩余天数
取所有dim_日期,其中is_weekend为假,date_actual高于项目的最后计划日期
这里是一个数据摆弄:
使用一个运行总数来保留每个项目的剩余小时数。 并将其限制在一定范围内 在子查询中,它限制计算的最长日期。 这样它就不会从dim_日期开始计算下一个日期
SELECT
id as projectId
, date_actual as weekDay
, row_number()
over (partition by id order by date_actual desc)-1 as daysRemaining
FROM
(
SELECT
p.id, d.date_actual, p.head_count
, p.last_scheduled_date, p.remaining_hours_required
,(p.remaining_hours_required
- sum(8*head_count) over
(partition by p.id order by date_actual)
) as remaining_hours
FROM projects p
JOIN dim_dates d
ON (d.date_actual > p.last_scheduled_date
AND d.date_actual <= p.last_scheduled_date + cast(ceil(((p.remaining_hours_required/5.0)*7.0)/(8*p.head_count))+1 as int)
AND d.is_weekend IS FALSE)
) q
WHERE remaining_hours > (-8*head_count)
ORDER BY id, date_actual;
SQL FIDLE上的测试查看您的FIDLE,您只需计算所需的天数,而不是使用4?@JuanCarlosOropeza我不确定您的意思如果我没有弄错的话,首先必须从dim_日期中获取每一行,并用行号注释,然后继续过滤。虽然我的问题没有提到,正如你可以想象的那样,dim_日期非常大,而且在2018-01-04之后选择所有行需要做大量的工作,但是必须先选择dim_日期中的每一行吗?这有点超出了我的SQL技能,所以我在使用它的同时学习它在做什么。子查询将选择dim_date中的每一行(不包括过滤掉的行),但我不知道是否会发生这种情况。从子查询本身选择*将生成每个dim_date。@EmilAhlbäck我在子查询中为其添加了额外的条件。干杯!聪明的:
SELECT
id as projectId
, date_actual as weekDay
, row_number()
over (partition by id order by date_actual desc)-1 as daysRemaining
FROM
(
SELECT
p.id, d.date_actual, p.head_count
, p.last_scheduled_date, p.remaining_hours_required
,(p.remaining_hours_required
- sum(8*head_count) over
(partition by p.id order by date_actual)
) as remaining_hours
FROM projects p
JOIN dim_dates d
ON (d.date_actual > p.last_scheduled_date
AND d.date_actual <= p.last_scheduled_date + cast(ceil(((p.remaining_hours_required/5.0)*7.0)/(8*p.head_count))+1 as int)
AND d.is_weekend IS FALSE)
) q
WHERE remaining_hours > (-8*head_count)
ORDER BY id, date_actual;