在Oracle中,我想构建一个查询,计算从开始日期算起的星期一和星期四的数量。
例如:
从 20-MAY-18 到今天(星期四 - 5月31日 - 18日)
从5月20日至今,已经过了4个星期一和星期四(2个星期一和2个星期四)的总数。我希望在此查询中返回4。如果这个查询昨天(星期三30-MAY-18)运行,我想获得3个计数。
我想减去今天减去 20-MAY-18
的几周也许是这样的:
select ( TRUNC( SYSDATE, 'IW' ) - TRUNC( TO_DATE('20-MAY-18'), 'IW' ) ) / 7 * 2 from dual;
由于星期一和星期四,我两次乘以它。如果星期六还没有出现,那么由于本周它会给出错误的结果。
我无法指望将本周过去的工作日计算到按周数计算的时间。
我还需要能够改变选定的日期,而不是只在星期一和星期四被困住。
答案 0 :(得分:1)
您可以使用它来计算值:
计算包含开始日期的星期一与本周一之间的完整天数:
( 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
)
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;
答案 1 :(得分: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.您可以替换&#39; D&#39;格式化为&#39; DY&#39;并用WHERE d_date IN替换2,4(&#39; MON&#39;,&#39; THU&#39;)。