【问题标题】:Oracle 11g count how many Mondays and Thursdays from a starting date until nowOracle 11g 统计从开始日期到现在有多少个星期一和星期四
【发布时间】:2018-06-01 06:31:55
【问题描述】:

在 Oracle 中,我想构建一个查询,计算从开始日期算起有多少星期一和星期四已经过去了。

例如:

20-MAY-18今天(星期四 31-MAY-18)

从 5 月 20 日到今天,总共有 4 个星期一和星期四(2 个星期一和 2 个星期四)过去了。我想在这个查询中返回 4。如果这个查询在昨天(18 年 5 月 30 日星期三)运行,我想得到 3 个计数。

我正在考虑从 今天 减去 20-MAY-18

减去几周

可能是这样的:

select ( TRUNC( SYSDATE, 'IW' ) - TRUNC( TO_DATE('20-MAY-18'), 'IW' ) ) / 7 * 2 from dual;

因为星期一和星期四,我把它乘了两次。如果星期四还没有到来,那么它给出了错误的结果,因为这周。

我无法计算出这周过去的工作日数以按周数计算。

我还需要能够更改所选日期,而不是只停留在星期一和星期四。

【问题讨论】:

    标签: oracle oracle11g


    【解决方案1】:

    也许这会有所帮助。您可以为其添加更多逻辑。如果在 5 月 30 日运行,我不确定为什么它必须返回 3。他有什么想法?无论您何时运行它,您的开始/结束日期都是相同的,并且之间的天数也相同。如果他在 5 月 30 日跑步会发生什么?

    WITH mon_thur AS
    (
    SELECT to_date('20-MAY-2018') + LEVEL-1 start_date
         , to_date('31-MAY-2018') end_date
         , to_date('31-MAY-2018') - to_date('20-MAY-2018') days_between
     FROM dual
    CONNECT BY LEVEL <= to_date('31-MAY-2018') - to_date('20-MAY-2018')+1  -- days_between+1
    )
    SELECT count(*) number_of_mon_thu FROM
    (
    SELECT start_date, to_char(start_date, 'D') d_date 
      FROM mon_thur
    )
    WHERE d_date IN (2, 4)
    /
    

    输出为 4。您可以将 'D' 格式替换为 'DY' 并将 2, 4 替换为 WHERE d_date IN ('MON', 'THU')。

    【讨论】:

    • 如果昨天运行它应该是 3,因为星期四还没有发生
    • 如果您查看日历并计算从 20 日到昨天 30 日的星期一和星期四,您会看到有 3 个,因为今天将是另一个星期四。
    • @myhouse - 你的结束日期或之间的天数是否应该少一天?如果您在几天之内删除我的 +1,那么这将为您提供正确的结果。或者您必须在当天 - 星期四确定?
    • 是的,让我再进行一些测试,我会接受的。到目前为止,这行得通。是的,我想在今天之前确定。
    • 这并不适用于所有地区。 ALTER SESSION SET NLS_TERRITORY = 'DENMARK';(或周日不是一周的第一天的任何地区)并且代码不会按照您的预期进行。此外,它应该是 IN (1, 4)IN (2,5),因为星期四是星期一之后的 3 天(取决于星期一是第 1 天还是第 2 天)。
    【解决方案2】:

    你可以用它来计算值:

    计算包含开始日期的一周中的星期一与本周的星期一之间的完整天数:

    ( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) )
    

    除以 7 得到整周数:

     / 7
    

    乘以你想每周匹配的天数

    * 2
    

    然后调整它以删除在开始日期之前计算的星期一和星期四。如果开始日是星期一,则为 0 调整,周二至周四为 1,周五至周日为 2:

    - DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
              0, 0, -- Monday
              1, 1, -- Tuesday
              2, 1, -- Wednesday
              3, 1, -- Thursday
              4, 2, -- Friday
              5, 2, -- Saturday
              6, 2  -- Sunday
            )
    

    然后调整它以包括从本周的星期一到今天的天数:

    + DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
              0, 1, -- Monday
              1, 1, -- Tuesday
              2, 1, -- Wednesday
              3, 2, -- Thursday
              4, 2, -- Friday
              5, 2, -- Saturday
              6, 2  -- Sunday
            )
    

    SQL Fiddle

    Oracle 11g R2 架构设置

    CREATE TABLE table_name ( start_date ) AS
    SELECT DATE '2018-05-20' + LEVEL - 1
    FROM DUAL
    CONNECT BY DATE '2018-05-20' + LEVEL - 1 <= SYSDATE;
    

    查询 1

    SELECT start_date,
           TO_CHAR( start_date, 'DY' ) As day,
           ( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) ) / 7 * 2
           - DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
                    0, 0, 1, 1, 2, 1, 3, 1, 4, 2, 5, 2, 6, 2 )
           + DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
                    0, 1, 1, 1, 2, 1, 3, 2, 4, 2, 5, 2, 6, 2 ) AS num_mon_and_thurs
    FROM   table_name
    

    Results

    |           START_DATE | DAY | NUM_MON_AND_THURS |
    |----------------------|-----|-------------------|
    | 2018-05-20T00:00:00Z | SUN |                 4 |
    | 2018-05-21T00:00:00Z | MON |                 4 |
    | 2018-05-22T00:00:00Z | TUE |                 3 |
    | 2018-05-23T00:00:00Z | WED |                 3 |
    | 2018-05-24T00:00:00Z | THU |                 3 |
    | 2018-05-25T00:00:00Z | FRI |                 2 |
    | 2018-05-26T00:00:00Z | SAT |                 2 |
    | 2018-05-27T00:00:00Z | SUN |                 2 |
    | 2018-05-28T00:00:00Z | MON |                 2 |
    | 2018-05-29T00:00:00Z | TUE |                 1 |
    | 2018-05-30T00:00:00Z | WED |                 1 |
    | 2018-05-31T00:00:00Z | THU |                 1 |
    

    如果我想将星期一和星期四改为星期二、星期三、星期六怎么办?我该怎么做?

    SELECT start_date,
           TO_CHAR( start_date, 'DY' ) As day,
           ( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) ) / 7 * 3
           - DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
                    0, 0, 1, 0, 2, 1, 3, 2, 4, 2, 5, 2, 6, 3 )
           + DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
                    0, 0, 1, 1, 2, 2, 3, 2, 4, 2, 5, 3, 6, 3 ) AS num_tue_wed_sat
    FROM   table_name;
    

    SQLFIDDLE

    【讨论】:

    • 你的公式有效,我很感激你这样做,但我看不懂。我不明白你做了什么。
    • 如果我想把星期一和星期四改为星期二、星期三、星期六怎么办?我该怎么做?
    • @myhouse 已更新。
    猜你喜欢
    • 2014-02-23
    • 2020-07-02
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多