2017-07-14 69 views
1

我想編寫一個基於SQL Server中的日期時間和工作日查詢在我的輸出應該是這樣的:組數據通過15分鐘的間隔,並使用交叉表

enter image description here

我的表說明如下:

**Branch**(DateKey integer, 
    BranchName varchar2(20), 
    TransactionDate datetime, 
    OrderCount integer) 

    **Date**(DateKey integer PrimaryKey, 
    DayNameofWeek varchar2(15)) 

這是原始數據我有

Data

+0

這裏是一個非常類似的問題:https://stackoverflow.com/questions/830792/t-sql-round-to-nearest-15-minute-interval唯一的區別是,你會四捨五入到下一個15分鐘DOWN並且在這個問題中直接舍入到NEXT。 – swe

+0

您想僅在11:30至12:30之間的時間內進行查詢,或者可能會有更多的值? –

+0

@maulik它超過了這些值,這只是一個例子。我需要24小時。 – Shivang

回答

0

所以,這是一個相當長鏡頭,但我解決它的方式如下:

我創建了一個table valued function,這將需要一個date作爲參數,並在這一天找到所有15-minute間隔。 對於每一天它會從00:00, to 00:15, 00:3023:30, 23:4523:59。它也返回每個間隔start timeend time,因爲我們將需要使用此的每一行中的branch表檢查,如果他們屬於這個時間段,如果是這樣,在計算它

這是函數:

create function dbo.getDate15MinIntervals(@date date) 
returns @intervals table (
    [interval] int not null, 
    [dayname] varchar(20) not null, 
    interval_start_time datetime not null, 
    interval_end_time datetime not null 
) 
as 
begin 

    declare @starttime time = '00:00'; 
    declare @endtime time = '23:59'; 

    declare @date_start datetime; 
    declare @date_end datetime; 
    declare @min datetime; 

    select @date_start = cast(@date as datetime) + cast(@starttime as datetime), @date_end = cast(@date as datetime) + cast(@endtime as datetime); 

    declare @minutes table ([date] datetime) 

    insert into @minutes values (@date_start), (@date_end) -- begin, end of the day 

    select @min = DATEADD(mi, 0, @date_start) 

    while @min < @date_end 
    begin 
     select @min = DATEADD(mi, 1, @min) 
     insert into @minutes values (@min) 
    end 

    insert into @intervals 
    select ([row]-1)/15+1 intervalId, [dayname], min(interval_time) interval_start_time 

    > -- **NOTE: This line is the only thing you need to change:** 

    , DATEADD(ms, 59998, max(interval_time)) interval_end_time 


    from 
    (
     select row_number() over(order by [date]) as [row], [date], datename(weekday, [date]) [dayname], [date] interval_time 
     from @minutes 
    ) t 
    group by ([row]-1)/15+1, [dayname] 
    order by ([row]-1)/15+1 

    return 

end 

--example of calling it: 
select * from dbo.getDate15MinIntervals('2017-07-14') 

然後,我查詢您的branch表(你並不真正需要的Date表,平日現在你擁有了它的功能,但即使沒有,有一個在SQL Server中的DATENAME功能,從2008年你可以使用。

我想查詢你的表是這樣的:

select branchname, [dayname], ISNULL([11:30], 0) as [11:30], ISNULL([11:45], 0) as [11:45], ISNULL([12:00], 0) as [12:00], ISNULL([12:45], 0) as [12:45] 
from 
( 
    select intervals.[dayname] 
     , b.branchname 
     , convert(varchar(5), intervals.interval_start_time, 108) interval_start_time -- for hh:mm format 
     , sum(b.ordercount) ordercount 
    from branch b cross apply dbo.getDate15MinIntervals(CAST(b.TransactionDate as date)) as intervals 
    where b.transactiondate between interval_start_time and interval_end_time 
    group by intervals.[dayname], b.branchname, intervals.interval_start_time, intervals.interval_end_time 
) t 
pivot (sum(ordercount) for interval_start_time in ([11:30], [11:45] , [12:00], [12:45])) as p 

請注意我在PIVOT功能只使用間隔我可以爲您發佈的圖片中看到,當然你可以手工編寫這一天所有15-minute間隔 - 您只需要在pivot中寫入一次,並在select聲明中寫入一次 - 或者選擇性地生成此語句dynamically

+0

它不給我適當的時間間隔計數。例如,11:45 - 11:59它不能正確計數,11:59:28它的排除或可能是重複的,因爲2個記錄在11:59。 – Shivang

+0

儘管'BETWEEN'包含兩個日期,您可以用'> =和<='替換BETWEEN。 –

+0

它仍然是相同的輸出..你可以想到的任何其他解決方案? – Shivang

相關問題