【问题标题】:Change Date and group by Fiscal Month End按会计月底更改日期和组
【发布时间】:2010-11-05 21:02:04
【问题描述】:

我创建了下表(通过 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(例如 1/27/2007 -> 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 列中的财政月末分组。

【问题讨论】:

  • 您在这里使用什么数据库引擎?您还可以发布返回第一个输出的 SQL。
  • 你需要澄清这个问题。上表中的前 12 个条目的 Fiscal 为 0,那么这些日期是如何计算的?小时和重量是否与会计月份的计算有某种关联?我们是否将多行连接在一起以计算单行(例如,将多行中的 AAA 条目连接起来以确定实际的会计月份)?归结为基本问题...
  • 第一步是将数据放入两个单独的表中。您希望第二个表代表会计月份,每个月份都有一个开始日期和一个结束日期。从上面的 UNION ALL 混乱中整理出来是愚蠢的 - 太像努力工作了。有了该表,分组变得非常简单;您按财政结束分组并按“日期在财政开始和财政结束之间”加入; BETWEEN/AND 的包含范围在这里非常有用。

标签: sql group-by calendar union


【解决方案1】:

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

我称您的表为 SO。我还必须将您的列重命名为 cHour 和 CDate,因为在 Oracle 中,至少 Date 是保留字。 您很可能直接从源表创建表“主”和“财政”表以加快速度:

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 的行)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多