2009-06-26 7 views
0

對於純樸的緣故,我會做出一個類似的例子,我有什麼:SQL:如何組通過自定義年份

假設一個數據庫有訂單的表的訂購日期字段和公司字段。然後有一張公司表,每個記錄都有一個YearEndingDate(表示年結束於每年的這一天,例如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

您應指定您所使用的數據庫管理系統。 – ahsteele 2009-06-26 22:47:15

+0

我故意拋開這個,因爲我必須在本地SQLite數據庫和中央SqlServer中執行此操作。 – Jared 2009-06-27 01:33:27

回答

1

不知道你正在使用什麼RDMS,但這應該做的伎倆。 datepart和dateadd是tsql特有的,但我假設你可以在任何你使用的平臺上訪問類似的函數。在哪裏決定使用哪一年的價值。

答:

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