好的,我的查询工作正常,从12月1日(我们的销售财年开始)计算周数。
现在要求已经改变了。我仍然需要根据字段(Invoice_Date)计算周数。但是,现在我需要从最近的星期一到12月1日开始计算,而不是从12月1日(12月1日到7日,第1周等)开始计算。据我了解,ISO周是我正在寻找的,但从1月1日开始。如何从12月1日开始修改它?
非常感谢任何帮助。
答案 0 :(得分:0)
select next_day(to_date('0112' || to_char(sysdate, 'YYYY'),'ddmmyyyy') - 1, 'MONDAY') dec_mon from dual;
给你当年12月的第一个星期一
周数仅为ceil((sysdate - dec_mon)/7)
。
如果您希望在12月1日之前的上周一,可以通过以下方式获取:
select next_day(to_date('2511' || to_char(sysdate, 'YYYY'),'ddmmyyyy') - 1, 'MONDAY')
from dual;
答案 1 :(得分:0)
在这个提议的解决方案中,我首先构建一个“帮助表”,显示每个会计年度的Monday_from
和Monday_to
(在第三个CTE中,名为ranges
)。然后我构建了一些测试日期 - 我很懒,我应该使用to_date()
所以我也可以包含时间组件。实际解决方案中的连接条件(在代码末尾)被写入,因此无需修改具有非零“时间”组件的日期即可工作。
我使用了Oracle 11.2的优点,它允许我们在CTE声明中给出列别名 - 否则列别名需要在相应的SELECT
内移动。否则,解决方案至少应该适用于Oracle 9及更高版本(我认为)。
with
y ( dt ) as (
select add_months(date '2000-12-01', 12 * level )
from dual
connect by level <= 30
),
m ( dt ) as (
select trunc(dt, 'iw') + case when dt - trunc(dt, 'iw') <= 3 then 0 else 7 end
from y
),
ranges ( monday_from, monday_to ) as (
select dt, lead(dt) over (order by dt) - 1
from m
),
test_dates ( t_date ) as (
select date '2013-02-23' from dual union all
select date '2008-12-01' from dual union all
select date '2008-04-28' from dual union all
select date '2016-11-29' from dual
)
select t_date, monday_from, 1 + trunc((t_date - monday_from)/7) as week_no
from test_dates t inner join ranges r
on t.t_date >= r.monday_from and t.t_date < r.monday_to
;
T_DATE MONDAY_FROM WEEK_NO
------------------- ------------------- ----------
2008-04-28 00:00:00 2007-12-03 00:00:00 22
2008-12-01 00:00:00 2008-12-01 00:00:00 1
2013-02-23 00:00:00 2012-12-03 00:00:00 12
2016-11-29 00:00:00 2016-11-28 00:00:00 1
答案 2 :(得分:0)
使用以下函数返回距离任何给定日期最近的星期一:
NEXT_DAY(some_date-4,'Monday')
如此查询所示:
with dts(some_date) as (
select date '2006-12-1' from dual
union all
select add_months(some_date,12)
from dts
where some_date <= date '2014-12-1'
)
select some_date
, next_day(some_date-4,'monday') nearest
, some_date - next_day(some_date-4,'monday') dist
from dts;
SOME_DATE NEAREST DIST
----------- ----------- ----------
01-DEC-2006 04-DEC-2006 -3
01-DEC-2007 03-DEC-2007 -2
01-DEC-2008 01-DEC-2008 0
01-DEC-2009 30-NOV-2009 1
01-DEC-2010 29-NOV-2010 2
01-DEC-2011 28-NOV-2011 3
01-DEC-2012 03-DEC-2012 -2
01-DEC-2013 02-DEC-2013 -1
01-DEC-2014 01-DEC-2014 0
01-DEC-2015 30-NOV-2015 1
10 rows selected