【问题标题】:Count Specific Days of Week in Time Period计算时间段中一周中的特定天数
【发布时间】:2023-04-10 01:03:01
【问题描述】:

我正在尝试查找一个月内的 Xdays 数(周一、周五等)。我总是可以遍历一个月内的几天,找到他们的星期几,总结并存储它,但我认为有更好的方法来做到这一点。

理想情况下,我希望得到“2015 年 9 月有多少个星期一、星期二和星期五(或任何日子)?”的结果。

我可以找到如何在一个时间段内获得工作日。我可以从数据库中已经输入的日期中获取此类信息,但我想知道有一个星期二,即使那天没有数据。

【问题讨论】:

  • 您可能会编写一个脚本来检查该月的第一天是什么,以及该月有多少天并从那里推断出来。

标签: oracle function date


【解决方案1】:

Michiel T 答案的变体,使用 trunc 和月份格式参数来获取月份的第一天:

select count(*)
from
  (select trunc(sysdate, 'MM') + (level - 1) dt
   from dual
   connect by level <= extract(day from last_day(trunc(sysdate, 'MM'))))
where to_char(dt, 'FMDAY') = 'MONDAY'

【讨论】:

    【解决方案2】:

    迭代方法,基于 PL/SQL PIPELINED functions

    CREATE OR REPLACE TYPE days_tbl AS TABLE OF DATE;
    
    CREATE OR REPLACE FUNCTION days_for_month(basedate IN DATE)
    RETURN days_tbl PIPELINED
    AS
        month VARCHAR(2);
        thedate DATE := TRUNC(basedate,'MON');
    BEGIN
        LOOP
          PIPE ROW(thedate);
          EXIT WHEN thedate = LAST_DAY(thedate);
          thedate := thedate + 1;
        END LOOP;
    END;
    

    基本用法:

    SELECT COLUMN_VALUE
      FROM TABLE(days_for_month(SYSDATE)) 
      WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') = 'MONDAY';
    

    该功能可能已针对您的特定需求进行了优化(按名称查找给定日期),但保持其更通用允许一些使用灵活性,例如:

    SELECT COLUMN_VALUE
      FROM TABLE(days_for_month(SYSDATE)) 
      WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') IN ('SUNDAY','SATURDAY');
    

    举个例子:

    “2015 年 9 月有多少个星期一、星期二和星期五(或任何日子)?”。

    SELECT COUNT(*)
      FROM TABLE(days_for_month(TO_DATE('09-2015','MM-YYYY'))) 
      WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') IN ('MONDAY','TUESDAY','FRIDAY');
    

    制作:

    COUNT(*)
    13
    

    或者如果您需要详细信息:

    SELECT T.D, COUNT(*)
      FROM TABLE(days_for_month(TO_DATE('09-2015','MM-YYYY'))),
           (SELECT 'MONDAY' AS D FROM DUAL UNION
            SELECT 'TUESDAY' FROM DUAL UNION
            SELECT 'FRIDAY' FROM DUAL) T
      WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') = T.D
      GROUP BY T.D
    

    生产:

    D       COUNT(*)
    TUESDAY 5
    FRIDAY  4
    MONDAY  4
    

    【讨论】:

      【解决方案3】:

      这会给你一个给定月份的第一个星期二:

      NEXT_DAY(TRUNC(DATE '2014-09-19', 'MM')-1, 'TUESDAY')
      

      这会为您提供给定月份的最后一个星期二:

      NEXT_DAY(LAST_DAY(DATE '2014-09-19')-7, 'TUESDAY')
      

      所以你可以把它组合成:

      SELECT 1 + (NEXT_DAY(LAST_DAY(DATE '2014-09-19')-7, 'TUESDAY') - NEXT_DAY(TRUNC(DATE '2014-09-19', 'MM')-1, 'TUESDAY'))/7 AS TUESDAYS_IN_MONTH
      FROM dual;
      

      【讨论】:

      • 您可能希望整天检查这个。它没有给出 2014 年 9 月星期一的正确答案。
      【解决方案4】:

      在 Oracle 中,您可以使用日期格式掩码来查看某个日期是哪一天。以下示例计算 2015 年第 9 个月(9 月)的所有星期一

      SELECT COUNT(*)
      FROM   ( SELECT RTRIM(TO_CHAR(TO_DATE(TO_CHAR(LEVEL, '09')||'09'||'2015','DDMMYYYY'),'DAY')) AS days
               FROM dual
               WHERE ROWNUM <= EXTRACT(DAY FROM LAST_DAY(TO_DATE('09'||'2015','MMYYYY')))
               CONNECT BY LEVEL=ROWNUM
             )
      WHERE  days = 'MONDAY'
             ;
      

      【讨论】:

        【解决方案5】:

        正如@Leeish 所说:

        “您可能可以编写一个脚本来检查第一天 该月是,该月有多少天,并从 那里”

        (我只能访问 MS Sql 但应该类似)

        这将以文本格式为您提供每月的第一天(例如“星期一”):

        SELECT DATENAME(dw,DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0))
        

        这会告诉你这个月有多少天:

        select datediff(d,  GETDATE(), dateadd(m, 1,  GETDATE()))
        

        希望这会有所帮助。

        【讨论】:

        • DATEDIFFDATENAMEGETDATE 不是 Oracle 函数。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多