2014-11-24 60 views
1

我被時期試圖組一串日期,即​​「月」通過DATEADD分組日期和DATEDIFF

首先我聲明表:

--inserts 36 dates every 10 days 
create table sales (sales_date datetime, sales_amount decimal(12,2)) 
insert into sales (sales_date,sales_amount) 
select '20140101',1000 union all 
select '20140110',1000 union all 
select '20140120',1000 union all 
select '20140130',1000 union all 
... 

然後我通過查詢分組期間條目(尺寸=精度*月)

DECLARE @precision int = 1 --number of months 

SELECT 
dateadd(month, (datediff(month, 0, sales_date)/@precision) * @precision, 0) as FromDate, 
dateadd(month, @precision + (datediff(month, 0, sales_date)/@precision) * @precision, 0) as ToDate, 
count(*) as number 
FROM sales 
GROUP BY 
dateadd(month, (datediff(month, 0, sales_date)/@precision) * @precision, 0), 
dateadd(month, @precision + (datediff(month, 0, sales_date)/@precision) * @precision, 0) 

結果:

Test 1 : precision of 1 month 
From : 01/01/2014, To : 01/02/2014, number : 4 
From : 01/02/2014, To : 01/03/2014, number : 2 
From : 01/03/2014, To : 01/04/2014, number : 3 
From : 01/05/2014, To : 01/06/2014, number : 4 
From : 01/06/2014, To : 01/07/2014, number : 3 
From : 01/07/2014, To : 01/08/2014, number : 3 
From : 01/08/2014, To : 01/09/2014, number : 3 
From : 01/09/2014, To : 01/10/2014, number : 3 
From : 01/10/2014, To : 01/11/2014, number : 3 
From : 01/11/2014, To : 01/12/2014, number : 3 
From : 01/12/2014, To : 01/01/2015, number : 2 

Test 2 : precision of 2 months 
From : 01/01/2014, To : 01/03/2014, number : 6 
From : 01/03/2014, To : 01/05/2014, number : 6 
From : 01/05/2014, To : 01/07/2014, number : 7 
From : 01/07/2014, To : 01/09/2014, number : 6 
From : 01/09/2014, To : 01/11/2014, number : 6 
From : 01/11/2014, To : 01/01/2015, number : 5 

Test 3 : precision of 3 months 
From : 01/01/2014, To : 01/04/2014, number : 9 
From : 01/04/2014, To : 01/07/2014, number : 10 
From : 01/07/2014, To : 01/10/2014, number : 9 
From : 01/10/2014, To : 01/01/2015, number : 8 

Test 4 : precision of 4 months 
From : 01/01/2014, To : 01/05/2014, number : 12 
From : 01/05/2014, To : 01/09/2014, number : 13 
From : 01/09/2014, To : 01/01/2015, number : 11 

一切工作正常,直到測試5:

Test 5 : precision of 5 months 
From : 01/10/2013, To : 01/03/2014, number : 6 
From : 01/03/2014, To : 01/08/2014, number : 16 
From : 01/08/2014, To : 01/01/2015, number : 14 

第一行很討厭,我需要它在2014年1月1日像以前的精度

有什麼辦法來克服這個問題開始?

+0

我不明白你是如何得到你得到的輸出,也就是說,我期望看到''FROM:''開始選擇列列表,但我不這樣做,所以這會導致我相信有一箇中間步驟你沒有在這裏展示給我們,這可能是你的「翻譯」錯誤發生的地方。 – 2014-11-24 16:42:07

+0

'和WHERE的sales_date不爲空......這一行不需要'AND' – Tanner 2014-11-24 16:43:34

+0

結果只是來自我的C#單元測試,但sql server提供的完全相同;無論如何插入和查詢 – codablank1 2014-11-24 16:45:02

回答

0

你並不需要通過精密乘以精度爲FROM

這裏分裂,再次發生了什麼

datediff(month, 0, sales_date)/5 -> 273.6 as it is integer division, it is converting to 273 

進一步273*5 = 1365乘以(SO 3月是失去了應有的到整數除法)

所以這一塊應該爲你

DECLARE @precision int = 5 --number of months 

SELECT 
dateadd(month, (datediff(month, 0, sales_date)) , 0) as [From], 
dateadd(month, @precision + (datediff(month, 0, sales_date)) , 0) as [To], 
count(*) as number 
FROM sales 
GROUP BY 
dateadd(month, (datediff(month, 0, sales_date)) , 0), 
dateadd(month, @precision + (datediff(month, 0, sales_date)), 0) 
工作
+0

請查看[link](http://dba.stackexchange.com/a/17674/38687)關於'/ @precision)的必要性* @ precision' ;沒有它,每個月有一個期間 – codablank1 2014-11-25 16:37:32

+0

@ codablank1,然後使用精度爲5.0 – radar 2014-11-25 17:09:52

+0

@ codablank1,我仍然有精度在第二,所以你會得到所有點 – radar 2014-11-25 17:32:38