按财政月末更改日期和组

时间:2009-06-25 14:56:28

标签: sql group-by calendar union

我创建了下表(通过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

我想要检索:

    ID      Date        Hour    Weight
    AAA     1/28/2009   10  10
    AAA     2/27/2009   50  50
    AAA     3/29/2009   20  20

首先应将DATE列转换为下一个会计月末FISCAL(例如,2007年1月27日 - > 1/28 / 2009,1 / 30/2009 - > 2/27/2009等。然后按该值分组。

我能够使用:

    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

但这只是按日历分组,而不是根据我在 FISCAL 栏中的财政月份结束。

1 个答案:

答案 0 :(得分:1)

您不应将财务日期合并到表中。但是使用现在的表格,您可以首先使用财政“期间”创建一个表(使用WITH,因此不需要特殊的权限),并将此表与主表连接。

我打电话给你的桌子。我还必须将列重命名为cHour和CDate,因为在Oracle中至少Date是一个保留字。 您很可能直接从源表创建表'main'和表'fiscal'来加快速度:

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

另请注意,您的示例数据存在错误;最后一段时间的重量应为40(日期为2/27和2/28的行。)