Página 1 de 1
Semana do mês (mas de acordo com a semana do calendario)
Enviado: Sex, 17 Out 2008 2:10 pm
por brauliomsf
Olá
alguém sabe teria uma function ou sql mesmo que me mostre a semana do mês mas com base no calendario, ou seja:
outubro de 2008 : semana 1 seria do dia 1 a 4
semana 2 seria do dia 5 a 11 e assim por diante
usando to_char(data_qualquer,'W')
mostra a semana do mês mas sempre quebrando de 7 em 7 , ou seja: semana1 (do dia 1 ao 7), semana 2 (do dia 8 ao 14).....
Grato
Enviado: Sex, 17 Out 2008 5:31 pm
por dr_gori
Olha só:
Fiz uma tabela que contém datas de 1 até o outro mês:
Selecionar tudo
select trunc(to_date('01-mar-2008'),'mm')+rownum-1 dt
from all_objects
where rownum<=35
Ou seja:
Selecionar tudo
SQL> select trunc(to_date('01-mar-2008'),'mm')+rownum-1 dt
2 from all_objects
3 where rownum<=35
4 /
DT
---------
01-MAR-08
02-MAR-08
03-MAR-08
04-MAR-08
05-MAR-08
06-MAR-08
07-MAR-08
08-MAR-08
09-MAR-08
10-MAR-08
11-MAR-08
12-MAR-08
13-MAR-08
14-MAR-08
15-MAR-08
16-MAR-08
17-MAR-08
18-MAR-08
.
.
.
Agora que temos essa tabela, eu fiz assim:
Selecionar tudo
SELECT
dt
, TO_CHAR( dt, 'DY' , 'NLS_DATE_LANGUAGE=PORTUGUESE' ) dia
, CASE
WHEN dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') < TRUNC(dt,'MM') THEN 1
ELSE TO_CHAR (dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') , 'W')+1
END semana
FROM (SELECT TRUNC(TO_DATE('01-MAR-2008'),'MM')+ROWNUM-1 dt
FROM all_objects
WHERE ROWNUM<=35
)
Vamos aos testes:
Selecionar tudo
SQL> SELECT
2 dt
3 , TO_CHAR( dt, 'DY' , 'NLS_DATE_LANGUAGE=PORTUGUESE' ) dia
4 , CASE
5 WHEN dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') < TRUNC(dt,'MM') THEN 1
6 ELSE TO_CHAR (dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') , 'W')+1
7 END semana
8 FROM (SELECT TRUNC(TO_DATE('01-MAR-2008'),'MM')+ROWNUM-1 dt
9 FROM all_objects
10 WHERE ROWNUM<=35
11 )
12 /
DT DIA SEMANA
--------- --------- ----------
01-MAR-08 SAB 1
02-MAR-08 DOM 2
03-MAR-08 SEG 2
04-MAR-08 TER 2
05-MAR-08 QUA 2
06-MAR-08 QUI 2
07-MAR-08 SEX 2
08-MAR-08 SAB 2
09-MAR-08 DOM 3
10-MAR-08 SEG 3
11-MAR-08 TER 3
DT DIA SEMANA
--------- --------- ----------
12-MAR-08 QUA 3
13-MAR-08 QUI 3
14-MAR-08 SEX 3
15-MAR-08 SAB 3
16-MAR-08 DOM 4
17-MAR-08 SEG 4
18-MAR-08 TER 4
19-MAR-08 QUA 4
20-MAR-08 QUI 4
21-MAR-08 SEX 4
22-MAR-08 SAB 4
DT DIA SEMANA
--------- --------- ----------
23-MAR-08 DOM 5
24-MAR-08 SEG 5
25-MAR-08 TER 5
26-MAR-08 QUA 5
27-MAR-08 QUI 5
28-MAR-08 SEX 5
29-MAR-08 SAB 5
30-MAR-08 DOM 6
31-MAR-08 SEG 6
01-APR-08 TER 1
02-APR-08 QUA 1
DT DIA SEMANA
--------- --------- ----------
03-APR-08 QUI 1
04-APR-08 SEX 1
35 rows selected.
SQL>
Vamos para outro mês qualquer (JUNHO):
Selecionar tudo
SQL> SELECT
2 dt
3 , TO_CHAR( dt, 'DY' , 'NLS_DATE_LANGUAGE=PORTUGUESE' ) dia
4 , CASE
5 WHEN dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') < TRUNC(dt,'MM') THEN 1
6 ELSE TO_CHAR (dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') , 'W')+1
7 END semana
8 FROM (SELECT TRUNC(TO_DATE('01-jun-2008'),'MM')+ROWNUM-1 dt
9 FROM all_objects
10 WHERE ROWNUM<=35
11 )
12 /
DT DIA SEMANA
--------- --------- ----------
01-JUN-08 DOM 1
02-JUN-08 SEG 1
03-JUN-08 TER 1
04-JUN-08 QUA 1
05-JUN-08 QUI 1
06-JUN-08 SEX 1
07-JUN-08 SAB 1
08-JUN-08 DOM 2
09-JUN-08 SEG 2
10-JUN-08 TER 2
11-JUN-08 QUA 2
DT DIA SEMANA
--------- --------- ----------
12-JUN-08 QUI 2
13-JUN-08 SEX 2
14-JUN-08 SAB 2
15-JUN-08 DOM 3
16-JUN-08 SEG 3
17-JUN-08 TER 3
18-JUN-08 QUA 3
19-JUN-08 QUI 3
20-JUN-08 SEX 3
21-JUN-08 SAB 3
22-JUN-08 DOM 4
DT DIA SEMANA
--------- --------- ----------
23-JUN-08 SEG 4
24-JUN-08 TER 4
25-JUN-08 QUA 4
26-JUN-08 QUI 4
27-JUN-08 SEX 4
28-JUN-08 SAB 4
29-JUN-08 DOM 5
30-JUN-08 SEG 5
01-JUL-08 TER 1
02-JUL-08 QUA 1
03-JUL-08 QUI 1
DT DIA SEMANA
--------- --------- ----------
04-JUL-08 SEX 1
05-JUL-08 SAB 1
35 rows selected.
SQL>
Provavelmente deve existir um jeito mais fácil!!!
Esse tópico sempre me ajuda nessa horas:
http://glufke.net/oracle/viewtopic.php?t=22
Enviado: Ter, 04 Nov 2008 12:01 am
por margaridi
Criei uma função para te ajudar.
Segue abaixo o código da mesma e um exemplo de uso.
Se tiver dúvidas, mande msg.
Abraço.
Selecionar tudo
declare
vCurrentWeek number(1);
vWeek1 number(2);
vWeek2 number(2);
vWeek3 number(2);
vWeek4 number(2);
vWeek5 number(2);
--------------------------------------------------------------------------
-- Function fFindWeek
-- A partir de uma data qualquer, a função calcula a semana atual, de
-- acordo com o calendário comercial, sendo que cada semana começa
-- no domingo e termina no sábado
--------------------------------------------------------------------------
-- Desenvolvedor: Margaridi, Marco Aurélio (marco@margaridi.com)
-- Data : 04/11/2008
--------------------------------------------------------------------------
-- Parâmetros:
-- ffw_date_to_test in date -- a data a ser testada
-- ffw_week_1_last_day out number -- o último dia da primeira semana
-- ffw_week_2_last_day out number -- o último dia da segunda semana
-- ffw_week_3_last_day out number -- o último dia da terceira semana
-- ffw_week_4_last_day out number -- o último dia da quarta semana
-- ffw_week_5_last_day out number -- o último dia da quinta semana
-- ou ZERO se o mês só possuir 4 semanas
-- A função retorna a semana da data informada
--------------------------------------------------------------------------
function fFindWeek(ffw_date_to_test in date
,ffw_week_1_last_day out number
,ffw_week_2_last_day out number
,ffw_week_3_last_day out number
,ffw_week_4_last_day out number
,ffw_week_5_last_day out number) return number is
vWeekControl number(1) := 0;
vWeekDay number(1);
vMonthDay number(2);
vLastDay date;
vFirstDay date;
vDayToTest date;
vResult number;
begin
select last_day(sysdate)
into vLastDay
from dual;
vFirstDay := to_date('01'||to_char(vLastDay,'mmyyyy'),'ddmmyyyy');
vDayToTest := trunc(ffw_date_to_test);
while vFirstDay < vLastDay loop
select to_number(to_char(vFirstDay,'d'),'9')
, to_number(to_char(vFirstDay,'dd'),'99')
into vWeekDay
, vMonthDay
from dual;
if vFirstDay = vDayToTest then
vResult := vWeekControl + 1;
end if;
if vWeekDay = 7 then
vWeekControl := vWeekControl + 1;
case vWeekControl
when 1 then ffw_week_1_last_day := vMonthDay;
when 2 then ffw_week_2_last_day := vMonthDay;
when 3 then ffw_week_3_last_day := vMonthDay;
when 4 then ffw_week_4_last_day := vMonthDay;
when 5 then ffw_week_5_last_day := vMonthDay;
end case;
end if;
vFirstDay := vFirstDay + 1;
end loop;
ffw_week_5_last_day := vMonthDay;
if vWeekControl = 3 then
ffw_week_4_last_day := vMonthDay;
ffw_week_5_last_day := 0;
end if;
return(vResult);
end ffindweek;
--------------------------------------------------------------------------
-- Function fFindWeek (END)
--------------------------------------------------------------------------
begin
vCurrentWeek := ffindWeek(sysdate,vWeek1,vWeek2,vWeek3,vWeek4,vWeek5);
dbms_output.put_line(to_char(vCurrentWeek)||' | '||to_char(vWeek1)
||' | '||to_char(vWeek2)
||' | '||to_char(vWeek3)
||' | '||to_char(vWeek4)
||' | '||to_char(vWeek5));
end;
Re: Semana do mês (mas de acordo com a semana do calendario)
Enviado: Sex, 08 Dez 2023 11:30 am
por leodamian
Bom dia,
Estava procurando exatamente isso, extrair o numero da semana do mês. Mas fiquei com uma dúvida na query, o que significa " dt - 8 ", o que seria o 8 ?
CASE
WHEN dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') < TRUNC(dt,'MM') THEN 1
ELSE TO_CHAR (dt - 8+TO_CHAR( TRUNC(dt,'MM'), 'D') , 'W')+1
END semana
Obrigado pelo Post.