Je trouve cette question très confuse. Si la vraie question est de savoir comment calculer le quart d'une DATE
arbitraire alors il y a déjà plein d'exemples, comme :
- Oracle - diviser les dates en trimestres
- Rechercher le premier et le dernier jour du dernier trimestre dans ORACLE
Comment calculer le quart d'une date arbitraire
Quelques dates pour tester :
create table lots_of_dates as
select trunc(sysdate - level * 7) as d
from dual
connect by level <= 52;
Trouver les trimestres :
select d,
to_char(d, 'YYYY-Q') as QUARTER,
trunc(d, 'Q') as Q_FIRST_DAY,
add_months(trunc(d, 'Q'), 3) - 1 as Q_LAST_DAY
from lots_of_dates
order by 1;
Résultats :
D QUARTE Q_FIRST_DAY Q_LAST_DAY
------------------ ------ ------------------ ------------------
02-SEP-12 2012-3 01-JUL-12 30-SEP-12
09-SEP-12 2012-3 01-JUL-12 30-SEP-12
16-SEP-12 2012-3 01-JUL-12 30-SEP-12
23-SEP-12 2012-3 01-JUL-12 30-SEP-12
30-SEP-12 2012-3 01-JUL-12 30-SEP-12
07-OCT-12 2012-4 01-OCT-12 31-DEC-12
14-OCT-12 2012-4 01-OCT-12 31-DEC-12
21-OCT-12 2012-4 01-OCT-12 31-DEC-12
28-OCT-12 2012-4 01-OCT-12 31-DEC-12
04-NOV-12 2012-4 01-OCT-12 31-DEC-12
11-NOV-12 2012-4 01-OCT-12 31-DEC-12
...
Une procédure PL/SQL qui renvoie le premier et le dernier jour d'un trimestre
Les dates de début et de fin de trimestre sont constantes pour toutes les années à l'exception de la partie année. C'est à dire. le deuxième trimestre commence toujours le 1er avril et se termine le 30 juin de chaque année. Ainsi, le jour et le mois peuvent être fixés et seule la partie année doit être ajustée.
Une fonction ne peut renvoyer qu'une seule valeur, la sous-routine est donc implémentée en tant que procédure à la place. J'ai également fourni une fonction wrapper à la procédure :
-- raises CASE_NOT_FOUND for non-existing quarters
create or replace procedure get_quarter_days(
p_year in number,
p_quarter in number,
p_first_day out date,
p_last_day out date
) deterministic as
begin
case p_quarter
when 1 then
p_first_day := to_date(p_year || '-01-01', 'YYYY-MM-DD');
p_last_day := to_date(p_year || '-03-31', 'YYYY-MM-DD');
when 2 then
p_first_day := to_date(p_year || '-04-01', 'YYYY-MM-DD');
p_last_day := to_date(p_year || '-06-30', 'YYYY-MM-DD');
when 3 then
p_first_day := to_date(p_year || '-07-01', 'YYYY-MM-DD');
p_last_day := to_date(p_year || '-09-30', 'YYYY-MM-DD');
when 4 then
p_first_day := to_date(p_year || '-10-01', 'YYYY-MM-DD');
p_last_day := to_date(p_year || '-12-31', 'YYYY-MM-DD');
end case;
end;
/
show errors
create or replace function get_quarter_first_day(
p_year in number,
p_quarter in number
) return date deterministic as
v_first_day date;
v_last_day date;
begin
get_quarter_days(p_year, p_quarter, v_first_day, v_last_day);
return v_first_day;
end;
/
show errors
create or replace function get_quarter_last_day(
p_year in number,
p_quarter in number
) return date deterministic as
v_first_day date;
v_last_day date;
begin
get_quarter_days(p_year, p_quarter, v_first_day, v_last_day);
return v_last_day;
end;
/
show errors
Comment utiliser les sous-routines ci-dessus :
declare
v_first_day date;
v_last_day date;
begin
get_quarter_days(2011, 1, v_first_day, v_last_day);
dbms_output.put_line(v_first_day || ' - ' || v_last_day);
get_quarter_days(2012, 2, v_first_day, v_last_day);
dbms_output.put_line(v_first_day || ' - ' || v_last_day);
get_quarter_days(2013, 3, v_first_day, v_last_day);
dbms_output.put_line(v_first_day || ' - ' || v_last_day);
get_quarter_days(2014, 4, v_first_day, v_last_day);
dbms_output.put_line(v_first_day || ' - ' || v_last_day);
dbms_output.put_line(get_quarter_first_day(2015, 1) || ' - ' ||
get_quarter_last_day(2015, 1));
end;
/