Ir para o conteúdo principal

Função - Retorna períodos semanais do mês (domingo à sabado)

Essa função pode ser usada para casos em que é necessário coletar dados de uma base, onde será somado um valor agrupado por semana. Neste caso, o retorno da função será usado como filtro na consulta.

Exemplo:

Semana 1: R$ 100
Semana 2: R$: 188

Primeiramente criar a TYPE para que a função retorne uma tabela com várias colunas:

CREATE TYPE t_semanas_linha AS OBJECT (id integer, datainicio date, datafim date);
CREATE TYPE t_semanas_tabela IS TABLE OF t_semanas_linha;

Em seguida criar a função:

CREATE OR REPLACE FUNCTION f_semanas_mes (mesano varchar2) RETURN t_semanas_tabela AS
  linha_tabela 
  t_semanas_tabela := t_semanas_tabela();
  datainicio date;
  datafim date;
  contador integer := 1;
BEGIN
  FOR i IN 
   (SELECT dataatual, TO_CHAR(dataatual, 'D') as diasemana, LAST_DAY(dataatual) ultimodia
      FROM (select data_inicial + level - 1 dataatual
              from (select to_date('01/'||mesano, 'DD/MM/YYYY') data_inicial from dual)
           connect by level <= last_day(to_date(mesano, 'MM/YYYY')) - data_inicial + 1))
  LOOP
    if extract(day from i.dataatual) = 1 or i.diasemana = 1 then
        datainicio := i.dataatual;
    end if;
    
    if i.dataatual = i.ultimodia or i.diasemana = 7 then
        datafim := i.dataatual;
        linha_tabela.extend;
        linha_tabela(linha_tabela.last) := t_semanas_linha(contador, datainicio, datafim);
        contador := contador + 1;
    end if;
    
  END LOOP;

  RETURN linha_tabela;
END;

Chamada da função: 

SELECT * 
  FROM TABLE(f_semanas_mes('02/2020'))

Retorno: 

| ID | DATAINICIO | DATAFIM    |
--------------------------------
|  1 | 01/02/2020 | 01/02/2020 |
|  2 | 02/02/2020 | 08/02/2020 |
|  3 | 09/02/2020 | 15/02/2020 |
|  4 | 16/02/2020 | 22/02/2020 |
|  5 | 23/02/2020 | 29/02/2020 |