代码之家  ›  专栏  ›  技术社区  ›  Jared

SQL:如何按自定义年度分组

  •  0
  • Jared  · 技术社区  · 15 年前

    为了简单起见,我将用一个类似的例子来说明我所拥有的:

    假设一个数据库有一个订单表,其中有一个orderdate字段和一个company字段。然后有一个公司表,每个记录都有一个年终日期(这意味着每年的年终日期都是这样的,例如6/6)。

    我需要把每年的订单加起来。

    我想应该是这样的,但我不太明白:

    SELECT SUM(orderValue),
    CASE WHEN orderDate <= YearEndingDate THEN DatePart(year, orderDate)
    CASE WHEN orderDate > YearEndingDate THEN DatePart(year, orderDate) + 1
    END as Year
    FROM Orders
    INNER JOIN Company ON Company.companyID = Order.companyID
    GROUP By Company, Year
    

    有什么想法吗?

    1 回复  |  直到 15 年前
        1
  •  1
  •   ahsteele tungi52    15 年前

    不确定您使用的是什么RDM,但这应该可以做到这一点。datepart和dateadd是特定于tsql的,但我假设您可以在使用的任何平台上访问类似的函数。Where中的情况决定使用哪一年的值。

    答:

    select c.companyid
          ,yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,1,o.orderdate))) as yearending
          ,sum(ordervalue) as numberoforders
      from @orders o
           join @companies c
             on o.companyid = c.companyid
     where orderdate between case when (cast(yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate)) as datetime) >= o.orderdate)
                             then yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,-1,o.orderdate)))
                             else yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate))
                              end
                         and 
                             case when (cast(yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate)) as datetime) >= o.orderdate)
                             then yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate))
                             else yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,1,o.orderdate)))
                              end
     group by c.companyid, o.orderdate, yearendingdate
    

    解决问题的代码:

    declare @orders table (OrderDate datetime
                          ,CompanyID varchar(20)
                          ,OrderValue int)
    
    insert into @orders
    values (getdate(),'MS',2)
    
    insert into @orders
    values (DateAdd(year, -1, getdate()),'MS',3)
    
    insert into @orders
    values (DateAdd(year, -1, getdate()),'MS',1)
    
    insert into @orders
    values (DateAdd(year, 1, getdate()),'MS',4)
    
    insert into @orders
    values (DateAdd(year, 1, getdate()),'Blizzard',2)
    
    insert into @orders
    values (getdate(),'MS',11)
    
    declare @companies table (CompanyID varchar(20)
                             ,YearEndingDate varchar(20))
    
    insert into @companies
    values ('MS', '05/6')
    
    insert into @companies
    values ('Blizzard', '07/01')
    
    select c.companyid
          ,o.orderdate
          ,yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate)) as sameyear
          ,yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,1,o.orderdate))) as plusyear
          ,yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,-1,o.orderdate))) as minusyear
      from @orders o
           join @companies c
             on o.companyid = c.companyid
    
    select c.companyid
          ,yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,1,o.orderdate))) as yearending
          ,sum(ordervalue) as numberoforders
      from @orders o
           join @companies c
             on o.companyid = c.companyid
     where orderdate between case when (cast(yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate)) as datetime) >= o.orderdate)
                             then yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,-1,o.orderdate)))
                             else yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate))
                              end
                         and 
                             case when (cast(yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate)) as datetime) >= o.orderdate)
                             then yearendingdate + '/' + convert(varchar, datepart(yy, o.orderdate))
                             else yearendingdate + '/' + convert(varchar, datepart(yy, dateadd(yy,1,o.orderdate)))
                              end
     group by c.companyid, o.orderdate, yearendingdate