问题描述
我有一个日历表,其中显示所有日期,其中有一列指示日期是否为工作日 (1,0)。
有没有办法计算表格中两个日期之间的工作日数?
MILESTONE_TABLE
KEY | START_DATE | END_DATE |
---|---|---|
001 | 2018-12-31 | 2019-01-07 |
002 | 2018-01-03 | 2019-01-07 |
003 | 2018-01-02 | 2019-01-06 |
CALENDAR_TABLE
日期 | BUSInesS_DAY |
---|---|
2018-12-31 | 1 |
2019-01-01 | 0 |
2019-01-02 | 1 |
2019-01-03 | 1 |
2019-01-04 | 1 |
2019-01-05 | 1 |
2019-01-06 | 0 |
2019-01-07 | 1 |
DESIRED_RESULT
KEY | START_DATE | END_DATE | DAYS_BETWEEN |
---|---|---|---|
001 | 2018-12-31 | 2019-01-07 | 5 |
002 | 2018-01-03 | 2019-01-07 | 3 |
003 | 2018-01-02 | 2019-01-06 | 3 |
解决方法
以下是标准 SQL,但应该在 PostgreSQL 中工作。
SELECT COUNT(BUSINESS_DAY) AS DAYS_BETWEEN
FROM CALENDAR_TABLE
WHERE DATE >= '2018-12-31'
AND DATE <= '2019-01-07'
AND BUSINESS_DAY = 1;
如果您希望在结果表中包含其他元素(可能用于连接?),那么您可以将它们添加到 select
子句中。
在您编辑之后,我假设里程碑表中的数据是错误的并且开始日期是 2019 年。以下查询应该可以使用嵌套查询。已经使用 sqlite 进行了测试。
SELECT KEY,START_DATE,END_DATE,(
SELECT COUNT(BUSINESS_DAY)
FROM CALENDAR_TABLE
WHERE BUSINESS_DAY = 1
AND START_DATE <= DATE
AND DATE <= END_DATE
) AS DAYS_BETWEEN FROM MILESTONE_TABLE;
我建议不要使用 DATE
作为列的名称。
首先,根据问题描述,您的示例数据不会生成所需的结果。例如,关键 002 日期 2018-01-03 到 2019-01-07 包括日历表中的每个日期(以包含结束日期为准),因此是 6 个工作日而不是 3 个工作日。即使将 2018 年调整为 219 年也会改变结果但仍然没有产生预期的结果。现在进行所需的查询。
由于您的指标是 0 或 1,并且假设 1 表示业务,您只需对日历日期在指定日期范围内的 business_day 列求和。 (见fiddle)
select m.key,m.start_date,m.end_date,sum(c.business_day) days_between
from milestone m
join calendar c
on (c.cal_date between m.start_date and m.end_date)
group by m.key,m.end_date
order by m.start_date;