Je dois obtenir le premier jour et le dernier jour de la semaine de chaînes qui ont le format suivant:
'201118'
où 2011 est l'année et 18 le numéro de la semaine. Connaissant le numéro de la semaine, comment puis-je obtenir le premier et le dernier jour de la semaine?
Comment puis-je faire cela?
LA SEMAINE
select TRUNC(sysdate, 'iw') AS iso_week_start_date,
TRUNC(sysdate, 'iw') + 7 - 1/86400 AS iso_week_end_date
from dual;
MOIS
select
TRUNC (sysdate, 'mm') AS month_start_date,
LAST_DAY (TRUNC (sysdate, 'mm')) + 1 - 1/86400 AS month_end_date
from dual;
Si vous utilisez Oracle, ce code peut vous aider:
select
TRUNC(sysdate, 'YEAR') Start_of_the_year,
TRUNC(sysdate, 'MONTH') Start_of_the_month,
TRUNC(sysdate, 'DAY') start_of_the_week,
TRUNC(sysdate+365, 'YEAR')-1 End_of_the_year,
TRUNC(sysdate+30, 'MONTH')-1 End_of_the_month,
TRUNC(sysdate+6, 'DAY')-1 end_of_the_week
from dual;
select
TRUNC(sysdate, 'YEAR') Start_of_the_year,
TRUNC(sysdate+365, 'YEAR')-1 End_of_the_year,
TRUNC(sysdate, 'MONTH') Start_of_the_month,
TRUNC(sysdate+30, 'MONTH')-1 End_of_the_month,
TRUNC(sysdate, 'DAY')+1 start_of_the_week, -- starting Monday
TRUNC(sysdate+6, 'DAY') end_of_the_week -- finish Sunday
from dual;
SQL> var P_YEARWEEK varchar2(6)
SQL> exec :P_YEARWEEK := '201118'
PL/SQL procedure successfully completed.
SQL> with t as
2 ( select substr(:P_YEARWEEK,1,4) year
3 , substr(:P_YEARWEEK,5,2) week
4 from dual
5 )
6 select year
7 , week
8 , trunc(to_date(year,'yyyy'),'yyyy') january_1
9 , trunc(trunc(to_date(year,'yyyy'),'yyyy'),'iw') monday_week_1
10 , trunc(trunc(to_date(year,'yyyy'),'yyyy'),'iw') + (week - 1) * 7 start_of_the_week
11 , trunc(trunc(to_date(year,'yyyy'),'yyyy'),'iw') + week * 7 - 1 end_of_the_week
12 from t
13 /
YEAR WE JANUARY_1 MONDAY_WEEK_1 START_OF_THE_WEEK END_OF_THE_WEEK
---- -- ------------------- ------------------- ------------------- -------------------
2011 18 01-01-2011 00:00:00 27-12-2010 00:00:00 25-04-2011 00:00:00 01-05-2011 00:00:00
1 row selected.
Cordialement,
Rob.
SELECT NEXT_DAY (TO_DATE ('01/01/'||SUBSTR('201118',1,4),'MM/DD/YYYY')+(TO_NUMBER(SUBSTR('201118',5,2))*7)-3,'SUNDAY')-7 first_day_wk,
NEXT_DAY (TO_DATE ('01/01/'||SUBSTR('201118',1,4),'MM/DD/YYYY')+(TO_NUMBER(SUBSTR('201118',5,2))*7)-3,'SATURDAY') last_day_wk FROM dual
En supposant que vous entendez des semaines par rapport au premier jour de l'année ...
SELECT first_day_of_week, first_day_of_week+6 last_day_of_week
FROM (
SELECT TO_DATE(YEAR||'0101','YYYYMMDD') + 7 * (week-1) first_day_of_week
FROM (
SELECT substr(yearweek,1,4) YEAR, to_number(substr(yearweek,5)) week
FROM (
SELECT '201118' yearweek FROM dual
)
)
)
;
En fait, j'ai fait quelque chose comme ça:
select case myconfigtable.valpar
when 'WEEK' then to_char(next_day(datetime-7,'Monday'),'DD/MM/YYYY')|| ' - '|| to_char(next_day(datetime,'Sunday'),'DD/MM/YYYY')
when 'MONTH' then to_char(to_date(yearweek,'yyyyMM'),'DD/MM/YYYY') || ' - '|| to_char(last_day(to_date(yearweek,'yyyyMM')),'DD/MM/YYYY')
else 'NA'
end
depuis ( sélectionnez to_date (YEAR || '01 ',' YYYYMM ') + 7 * (SEMAINE - 1) datetime, yearweek à partir de ( select substr (yearweek, 1 , 4) ANNÉE, Au_numéro (sous-chaîne (yearweek, 5)) SEMAINE, Yearweek De (sélectionnez '201018' yearweek parmi dual ) ) ), Myconfigtable myconfigtable où myconfigtable.codpar = 'TYPEOFPERIOD'
Vous pouvez essayer cette approche:
Obtenez la date actuelle.
Ajoutez le nombre d'années qui est égal à la différence entre l'année de la date en cours et l'année spécifiée.
Soustrayez le nombre de jours correspondant au dernier jour de la semaine obtenu (et cela nous donnera le dernier jour d'une semaine).
Ajoutez le nombre de semaines correspondant à la différence entre le numéro de semaine de la dernière date obtenue et le numéro de semaine spécifié, ce qui donnera le dernier jour de la semaine souhaitée.
Soustrayez 6 jours pour obtenir le premier jour.
Une autre solution est
SELECT
ROUND((TRUNC(SYSDATE) - TRUNC(SYSDATE, 'YEAR')) / 7,0) CANTWEEK,
NEXT_DAY(SYSDATE, 'SUNDAY') - 7 FIRSTDAY,
NEXT_DAY(SYSDATE, 'SUNDAY') - 1 LASTDAY
FROM DUAL
Vous devez concat le cantweek avec l'année
Sauf s'il s'agit d'une conversion de données unique, il est probable que vous tirerez parti de l'utilisation d'un tableau de calendrier.
Avec un tel tableau, il est très facile de filtrer ou d'agréger des données pour des périodes non standard de addition aux semaines ISO régulières. Les semaines se comportent généralement un peu différemment selon les entreprises et leurs départements. Dès que vous quittez "ISO-land", les fonctions de date intégrées ne peuvent vous aider.
create table calender(
day date not null -- Truncated date
,iso_year_week number(6) not null -- ISO Year week (IYYYIW)
,retail_week number(6) not null -- Monday to Sunday (YYYYWW)
,purchase_week number(6) not null -- Sunday to Saturday (YYYYWW)
,primary key(day)
);
Vous pouvez créer des tables supplémentaires pour "purchase_weeks" ou "retail_weeks", ou simplement les agréger à la volée:
select a.colA
,a.colB
,b.first_day
,b.last_day
from your_table_with_weeks a
join (select iso_year_week
,min(day) as first_day
,max(day) as last_day
from calendar
group
by iso_year_week
) b on(a.iso_year_week = b.iso_year_week)
Si vous traitez un grand nombre d'enregistrements, l'agrégation à la volée ne fera pas une différence notable, mais si vous effectuez une seule ligne, vous bénéficierez également de la création de tables pour les semaines.
L'utilisation de tables de calendrier offre un avantage de performances subtil en ce que l'optimiseur peut fournir de meilleures estimations pour les colonnes statiques que pour les appels de fonction imbriqués add_months(to_date(to_char()))
.
Encore une autre solution (lundi est le premier jour):
select
to_char(sysdate - to_char(sysdate, 'd') + 2, 'yyyymmdd') first_day_of_week
, to_char(sysdate - to_char(sysdate, 'd') + 8, 'yyyymmdd') last_day_of_week
from
dual