2015-04-14 101 views
0

我之前需要它來顯示這樣的過去一個月內的動作與上月持平小時總量:兩個日期&GROUP BY列名之間的SQL SUM小時數?

___________________________________________ 
| Rank | Action | Month | Prev Month | 
|------|----------|------------|------------| 
| 1 | Action1 |  580.2 |  200.7 | 
| 2 | Action8 |  412.5 |  550.2 | 
| 3 | Action10 |  405.0 |  18.1 | 
--------------------------------------------- 

我有一個SQL表的格式:

_____________________________________________________ 
| Action |  StartTime  |  EndTime  | 
|---------|---------------------|---------------------| 
| Action1 | 2015-02-03 06:01:53 | 2015-02-03 06:12:05 | 
| Action1 | 2015-02-03 06:22:16 | 2015-02-03 06:25:33 | 
| Action2 | 2015-02-03 06:36:07 | 2015-02-03 06:36:49 | 
| Action1 | 2015-02-03 06:36:46 | 2015-02-03 06:48:10 | 
| ..etc | 20..-..-.. ...etc | 20..-..-.. ...etc | 
------------------------------------------------------- 

查詢會是什麼樣子?

編輯:

A ツ的回答讓我在正確的方向前進,但是我使用JOIN解決了這個問題。請參閱下面的解決方案。

+4

你能告訴我們你試圖做到這一點嗎? –

+1

你怎麼知道哪個月?這是否會來自用戶? –

+0

@wewesthemenace該月份將從日曆日期小部件中輸入,只有前10個結果將顯示在生成的表格中。 – ChiMo

回答

1

我研究多一點關於SQL Server之後,剛剛重新審視這個問題。

可以從查詢創建臨時表,然後在另一個查詢中使用 - 如果您願意,可以使用嵌套查詢
這樣的結果可以像JOIN一樣通過任何其他正常的表,而不會討厭CASE聲明。這也是有用的,以顯示第一查詢所需的其他DATAS像COUNT(DISTINCT ColumnName)

JOIN two SELECT statement results

SELECT TOP 10 
    t1.Action, t1.[Time], 
    COALESCE(t2.[Time],0) AS [Previous Period 'Time'], 
    COALESCE((((t1.[Time]*1.0) - (t2.[Time]*1.0))/(t2.[Time]*1.0)), -1) AS [Change] 
FROM 
    (
     SELECT 
      Action, 
      SUM(DATEDIFF(SECOND, StartTime, EndTime)) AS [Time], 
     FROM Actions 
     WHERE StartTime BETWEEN @start AND @end 
     GROUP BY Action 
    ) t1 
LEFT JOIN 
    (
     SELECT 
      Action, 
      SUM(DATEDIFF(SECOND, StartTime, EndTime)) AS [Time] 
     FROM Actions 
     WHERE StartTime BETWEEN @prev AND @start 
     GROUP BY Action 
    ) t2 
ON 
    t1.Action = t2.Action 
ORDER BY t1.[Time] DESC 

希望這個信息是有用的人。

0

也許你應該檢查在使用預處理的數據分組,像這樣:

select Action, SUM(Hours) 
    from (select Action, DATEDIFF('hh',StartTime, EndTime) as Hours 
    FROM Actions) 
group by Action 
0

我的假設是,你開始 - 結束時間跨度很短,你不必擔心跨日期2個月,那麼你可能需要這樣的事情:

select 
    dense_rank() over (order by Month desc) as Rank, 
    action, 
    Month, 
    PrevMonth 
from 
(
    select 
    action, 
    sum(case when StartTime >= @curMonth then hours else 0 end) as Month, 
    sum(case when StartTime >= @prevMonth and StartTime < @curMonth then hours else 0 end) as PrevMonth 
    from 
    (
    select 
     action, 
     StartTime, 
     datediff(second, StartTime, EndTime)/3600.0 as hours 
    from 
     yourtable 
) T1 
    group by 
     action 
) T2 

這個計算的持續時間是秒,然後用3600除以得到小時。排名僅基於當月。這期望你有兩個變量@curMonth和@prevMonth,它們的限制日期是一樣的,而且以後沒有數據。

SQL小提琴來進行測試:http://sqlfiddle.com/#!6/d64b7d/1

1

我改變了值的位,因爲只有一天是相當沉悶

INSERT INTO yourtable 
    ([Action], [StartTime], [EndTime]) 
VALUES 
    ('Action1', '2015-02-18 06:01:53', '2015-02-18 06:12:05'), 
    ('Action1', '2015-02-18 06:22:16', '2015-02-18 06:25:33'), 
    ('Action2', '2015-04-03 06:36:07', '2015-04-03 06:36:49'), 
    ('Action1', '2015-03-19 06:36:46', '2015-03-19 06:48:10'), 
    ('Action2', '2015-04-13 06:36:46', '2015-04-13 06:48:10'), 
    ('Action2', '2015-04-14 06:36:46', '2015-04-14 06:48:10') 
; 

現在定義的日期邊界:

declare @dateEntry datetime = '2015-04-03'; 

declare @date1 date 
     , @date2 date 
     , @date3 date; 

set @date1 = @dateEntry;    -- 2015-04-03 
set @date2 = dateadd(month,-1,@date1); -- 2015-03-03 
set @date3 = dateadd(month,-1,@date2); -- 2015-02-03 

選定的日期將包括2015-04-03 00:00之前開始並在2015-02-03 00:00之後開始的所有動作

select date1 = @date1 
    , date2 = @date2 
    , date3 = @date3 
    , [Action] 
    , thisMonth = 
     sum(
     case when Starttime between @date2 and @date1 
      then datediff(second, starttime, endtime)/360.0 
     end) 
    , lastMonth = 
     sum(
     case when Starttime between @date3 and @date2 
      then datediff(second, starttime, endtime)/360.0 
     end) 
    from yourtable 
    where starttime between @date3 and @date1 
    group by [Action] 

http://sqlfiddle.com/#!6/35784/5

+0

你非常有幫助!我沒有意識到你可以將CASE語句放在SUM字段中。唯一的問題是,即使當前月份的值爲NULL(即收集上個月的數據),它也會收集所有結果。將WHERE子句設置爲'WHERE(StartTime BETWEEN @ date2 AND @ date1)'從lastMonth'字段中刪除數據並添加'WHERE thisMonth IS NOT NULL'不起作用,因爲lastMonth不是有效的列名稱_ – ChiMo

+0

NULL結果可能是在GROUP BY語句之後使用'HAVING'省略。但是爲了顯示正確的結果,需要重複'CASE'語句的SUM。 – ChiMo