oracle - una - Crear vista con 365 días
vistas con parametros oracle (3)
Cómo crear una View
con todos los días del año. view
debería llenarse con fechas desde el JAN-01 hasta el 31 de diciembre. ¿Cómo puedo hacer esto en el oráculo?
si el año actual tiene 365 días, la view
debe tener 365 filas con fechas. si el año actual tiene 366 días, la view
debe tener 366 filas con fechas. Quiero que la view
tenga una sola columna de tipo DATE
Esta simple vista lo hará:
create or replace view year_days as
select trunc(sysdate, ''YYYY'') + (level-1) as the_day
from dual
connect by level <= to_number(to_char(last_day(add_months(trunc(sysdate, ''YYYY''),11)), ''DDD''))
/
Me gusta esto:
SQL> select * from year_days;
THE_DAY
---------
01-JAN-11
02-JAN-11
03-JAN-11
04-JAN-11
05-JAN-11
06-JAN-11
07-JAN-11
08-JAN-11
09-JAN-11
10-JAN-11
11-JAN-11
...
20-DEC-11
21-DEC-11
22-DEC-11
23-DEC-11
24-DEC-11
25-DEC-11
26-DEC-11
27-DEC-11
28-DEC-11
29-DEC-11
30-DEC-11
31-DEC-11
365 rows selected.
SQL>
La fecha se genera aplicando varias funciones de fecha de Oracle:
-
trunc(sysdate, ''yyyy'')
nos da el primero de enero para el año actual -
add_months(x, 11)
nos da el primero de diciembre -
last_day(x)
nos da el treinta y uno de diciembre -
to_char(x, ''DDD'')
nos da el número del treinta y uno de diciembre, 365 este año y 366 siguiente. - Esta última figura proporciona el límite superior para el generador de filas
CONNECT BY LEVEL <= X
Esto funciona bien en MS SQL
SELECT TOP (DATEDIFF(day, DATEADD(yy, DATEDIFF(yy,0,getdate()), 0), DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1))) n = ROW_NUMBER() OVER (ORDER BY [object_id]),
dateadd(day, ROW_NUMBER() OVER (ORDER BY [object_id]) - 1, DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) AS AsOfDate FROM sys.all_objects
Puedes usar la tabla piplined, debería ser algo como esto:
create or replace type year_date_typ as object (v_day date);
create or replace type year_date_tab as table of year_date_typ;
CREATE OR REPLACE FUNCTION get_dates(year IN VARCHAR2) RETURN year_date_tab PIPELINED IS
v_start_date date := to_date(''0101'' || year, ''ddmmyyyy'');
res year_date_typ := year_date_typ(null);
v_days_in_year integer := 365;
BEGIN
if to_char(last_day(to_date(''0102''||year, ''ddmmyyyy'')), ''dd'') = ''29'' then
v_days_in_year := 366;
end if;
FOR i in 0 .. v_days_in_year integer-1 LOOP
res.v_day := v_start_date + i;
pipe row(res);
END LOOP;
return;
END get_dates;
y puedes usarlo:
select * from table(get_dates(''2011''));