如何计算日历表中只有值为 1 的 2 列日期之间的天数 - postgreSQL?

Posted

技术标签:

【中文标题】如何计算日历表中只有值为 1 的 2 列日期之间的天数 - postgreSQL?【英文标题】:How do I count the number of days between 2 column dates that only have a value of 1 in the calendar table - postgreSQL? 【发布时间】:2021-03-04 22:31:18 【问题描述】:

我有一个日历表,它显示所有日期,并有一列指示日期是否为工作日 (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

DATE 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 中的 BETWEEN 包含在内,因此您的 DAYS_BETWEEN 将比您显示的计数大 1。这是您想要的还是您想要显示的计数? @Jessica,请在编辑后查看更新的答案 【参考方案1】:

以下是标准 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 子句中。

在您编辑之后,我假设milestone_table 中的数据是错误的,并且开始日期是 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 作为列名。

【讨论】:

【参考方案2】:

首先,鉴于问题描述,您的示例数据不会产生预期的结果。例如关键 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.start_date, m.end_date 
 order by m.start_date; 

【讨论】:

以上是关于如何计算日历表中只有值为 1 的 2 列日期之间的天数 - postgreSQL?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算定义自定义财务日历的两个日期之间的月数?

oracle 获取当天日期往前推2个工作日的日期

计算同一列中两个日期之间的日期

mysql 中怎么设置默认值为系统日期

如何在 SQL 中显示两个给定日期之间的所有日期

如何使用 SQL 获取 2 列之间日期差异的计数(值的分布)?