Alterar data e agrupar por Fiscal fim de mês
Pergunta
Eu criei a tabela seguinte (via 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
E eu gostaria de recuperar:
ID Date Hour Weight
AAA 1/28/2009 10 10
AAA 2/27/2009 50 50
AAA 3/29/2009 20 20
Em primeiro lugar converter a coluna DATA para o próximo fim de mês Fiscal Fiscal (por exemplo, 2007/01/27 -> 2009/01/28, 2009/01/30 -> 2009/02/27, etc.) e em seguida, grupo por esse valor.
Eu era capaz de 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
Mas isso apenas grupos de calendário datas, não de acordo com os fins fiscais mês eu tenho no FISCAL coluna.
Solução
Você não deve União as datas fiscais em sua mesa. Mas com a tabela que você tem agora, você pode primeiro criar uma tabela (usando COM, então há privilégios especiais são necessários) com os 'períodos' fiscais e participar desta mesa com sua mesa principal.
Eu chamei sua mesa para. Eu também tive que mudar o nome de suas colunas para Chour e CDate porque no Oracle pelo menos Data é uma palavra reservada. Você poderia muito provavelmente criar a tabela 'main' ea tabela 'fiscal' diretamente de suas tabelas de origem para acelerar as coisas:
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
Além disso, observe que os dados da amostra tem um erro; o peso para o seu último período deve ser de 40 (as linhas com datas 2/27 e 2/28).