Cambiar fecha y grupo por fin de mes fiscal
Pregunta
He creado la siguiente tabla (a través de UNION ALL):
ID Date Hour Weight Fiscal
AAA 1/27/2009 0 10 0
AAA 1/30/2009 0 20 0
AAA 2/14/2009 0 10 0
AAA 2/18/2009 0 20 0
AAA 2/27/2009 0 20 0
AAA 2/28/2009 0 20 0
AAA 1/14/2009 10 0 0
AAA 2/14/2009 20 0 0
AAA 2/16/2009 10 0 0
AAA 2/25/2009 10 0 0
AAA 2/26/2009 10 0 0
AAA 3/3/2009 20 0 0
NULL 0 0 0 1/28/2009
NULL 0 0 0 2/27/2009
NULL 0 0 0 3/29/2009
Y me gustaría recuperar:
ID Date Hour Weight
AAA 1/28/2009 10 10
AAA 2/27/2009 50 50
AAA 3/29/2009 20 20
Primero debe convertir la columna FECHA al próximo mes fiscal FISCAL (por ejemplo, 27/01/2007 - > 1/28/2009, 30/1/2009 - > 2/27/2009, etc. ) y luego agrupar por ese valor.
Pude usar:
SELECT ID
, left(CONVERT(VARCHAR(10)
, date, 111),7) as Date
, round(sum(Hours),0) as Hours
, round(sum(Weight),0) as Weight
FROM ...
GROUP BY ID
, left(CONVERT(VARCHAR(10), date, 111),7)
ORDER by ID ASC
, left(CONVERT(VARCHAR(10), date, 111),7) ASC
Pero eso solo se agrupa por fechas de calendario , no de acuerdo con el fin de mes fiscal que tengo en la columna FISCAL .
Solución
No debe unir las fechas fiscales en su tabla. Pero con la tabla como la tiene ahora, primero puede crear una tabla (usando WITH, por lo que no se necesitan privilegios especiales) con los 'períodos' fiscales y unir esta tabla con su tabla principal.
Llamé a su tabla SO. También tuve que cambiar el nombre de sus columnas a cHour y CDate porque en Oracle al menos Fecha es una palabra reservada. Es muy probable que pueda crear la tabla 'main' y la tabla 'fiscal' directamente desde sus tablas de origen para acelerar las cosas:
with fiscal_part as (
select fiscal
from SO
where fiscal is not null)
, fiscal as (
select fb.fiscal fiscal_begin
, min(fe.fiscal) fiscal_end
from fiscal_part fb right join
fiscal_part fe
on fe.fiscal > fb.fiscal
group by fb.fiscal)
, main as (
select *
from SO
where fiscal is null)
select main.ID
, fiscal.fiscal_end
, sum(main.cHour)
, sum(main.weight)
from main
join fiscal on main.cdate >= coalesce(fiscal.fiscal_begin, main.cdate)
and main.cdate < fiscal.fiscal_end
group by main.ID
, fiscal.fiscal_end
order by fiscal.fiscal_end
También tenga en cuenta que sus datos de muestra tienen un error; el peso para su último período debe ser 40 (las filas con las fechas 2/27 y 2/28).