2016-11-02 2 views
1

Ok, j'ai eu une requête qui fonctionne bien qui calcule le numéro de semaine à partir du 1er décembre (le début de notre année de vente).Numéro de semaine Oracle à partir de la date Semaine ISO Mais à partir du 1er décembre

Les exigences ont maintenant changé. J'ai encore besoin de calculer le numéro de la semaine en fonction du champ (Invoice_Date). Cependant, au lieu de commencer à compter du 1er décembre (1er au 7 décembre, semaine 1, etc.), je dois commencer à compter le lundi le plus proche du 1er décembre. Si je comprends bien, la semaine de l'ISO est un peu ce que je cherche, mais elle commence le 1er janvier. Comment puis-je modifier cela pour fonctionner à partir du 1er décembre?

Toute aide serait grandement appréciée.

+1

peut le lundi le plus proche est avant Décembre le 1sr , après ça, ou bien? Peut être utile pour montrer certaines dates et le numéro de la semaine que vous attendez. –

+0

Oui, le lundi le plus proche pourrait être avant le 1er décembre. J'essaie de comparer le même nombre de «dates de facture» au cours de l'année. J'ai besoin de la semaine fiscale pour TOUJOURS refléter lundi-dimanche. Au cours de l'exercice 2015, la première semaine se situerait entre le 1er décembre et le 7 décembre, mais la première semaine se déroulerait du 30 novembre au 26 décembre. Mes données ont la date de facturation pour chaque transaction. Je veux calculer le 'FW' (Fiscal Week) dans ma requête, donc si je fais un rapport comparant YTD semaine 50 de cette année à YTD semaine 50 de l'année dernière, je suis TOUJOURS traiter le même nombre de lundi, même nombre de mardi , etc. Ai-je un sens? – Jeff

Répondre

0

select next_day(to_date('0112' || to_char(sysdate, 'YYYY'),'ddmmyyyy') - 1, 'MONDAY') dec_mon from dual;
vous donne le premier lundi de l'année en cours Décembre

Nombre de semaine est juste ceil((sysdate - dec_mon)/7).

Si vous voulez lundi dernier avant le 1 décembre vous pouvez l'obtenir par:

select next_day(to_date('2511' || to_char(sysdate, 'YYYY'),'ddmmyyyy') - 1, 'MONDAY') 
from dual; 
0

Dans cette solution proposée, je construis une « table d'aide » d'abord, montrant le pour chaque exercice Monday_from et Monday_to (en le troisième CTE, nommé ranges). Ensuite, je construis quelques dates de test - j'étais paresseux, j'aurais dû utiliser to_date() pour que je puisse également inclure le composant d'heure du jour. La condition de jointure dans la solution actuelle (à la fin du code) est écrite afin qu'elle fonctionne sans modification pour les dates avec un composant "heure du jour" non nul. J'ai utilisé la fonction intéressante d'Oracle 11.2 qui nous permet de donner des alias de colonne dans la déclaration des CTE - sinon les alias de colonnes devraient être déplacés à l'intérieur des SELECT s respectifs. Sinon, la solution devrait fonctionner au moins pour Oracle 9 et plus (je pense).

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 
0

le plus proche lundi à toute une date donnée est retourné avec la fonction suivante:

NEXT_DAY(some_date-4,'Monday') 

comme le montre cette requête:

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