2015-08-31 42 views
1

我有一系列獨特的事件,可能會持續任意時間。由於事件可能會在特定的月份之前開始(在這種情況下,它會貢獻上個月以及當前的月份)並且在特定的月份之後完成,所以我需要計算事件對每月總計的貢獻小時數。查詢跨越月份邊界的事件的月總時數

的數據看起來類似:

Event | StartDate | EndDate | 
------------------------------- 
| 1 | 10/01/2015| 11/01/2015| 
| 2 | 20/12/2014| 9/01/2015 | 
| 3 | 25/01/2015| 14/02/2015| 

最後,我嘗試生成按月和年份合計每個月的「事件時間」(而不是每個事件分組名單 - 一個月內事件總結)。

說實話,我甚至不知道從哪裏開始。

+0

你的日期字段是'date'或'datetime'?因爲如果你現在想要計算小時數,全部都是24h –

+0

這裏的結束日期沒有意義。這是虛擬價值嗎?結束日期應該大於開始日期 活動開始日期結束日期 | 2 | 20/12/2015 | 9/01/2015 | –

+0

我的錯誤 - 我會糾正它 – skyman

回答

1

簡單的方法是使用月表,因爲你可以有空的月份。

create table months (
    month_id integer, 
    date_ini datetime, 
    date_end datetime 
) 

然後你做一個加入你的表。

SQL Fiddle Demo

WITH ranges as (
    SELECT * 
    FROM 
     months m 
     LEFT JOIN events e 
      on e.StartDate <= m.d_end 
      and e.EndDate >= m.d_begin 
) 
SELECT r.*, 
     DATEDIFF(hour, 
       CASE 
        WHEN StartDate > d_begin THEN StartDate 
        WHEN StartDate IS NULL THEN NULL 
        ELSE d_begin 
       END, 
       CASE 
        WHEN EndDate < d_end THEN EndDate 
        WHEN EndDate IS NULL THEN NULL 
        ELSE DATEADD(day,1,d_end) 
       END) as Hours 
FROM ranges r 

你有4案件

  • 一個事件,其中的開始和結束都是一個月
  • 一個事件,其中到底是超出月末
  • 一個事件開始內前後一個月結束
  • 一個月沒有事件。
+0

不知道我明白 - 你的意思是以這樣一種方式將一個月表加入到事件表中,使得聯合是事件列表(可能與跨越國界的事件重複)和時間他們在每個月內消費? – skyman

+0

我剛剛通過它......在第二排活動2將於20日開始,並在31日(第一張唱片)結束,然後在1日開始,並在下個月的9日結束 – skyman

+0

我認爲它可能需要CASE開關來設置月份中斷或IF然後? – skyman

0

嘗試。這將工作。

WITH EventInfo AS 
(
    SELECT EVENT, DATEDIFF(HOUR, StartDate,EndDate) AS hours, 
     DATEPART(MONTH, EndDate) AS Month, 
     DATEPART(Year, EndDate) AS Year 
    FROM events 
) 
SELECT Month, Year, SUM(hours) AS Total_hours 
FROM EventInfo 
Group By Month, Year 

這裏是SQLFiddle

+0

謝謝 - 也會嘗試這個以及 – skyman

+0

我不認爲這會考慮到您可能只能計算一個月內的事件的一部分? – skyman