按间隔15分钟分组数据并使用交叉表

时间:2017-07-14 06:27:57

标签: sql-server sql-server-2008

我正在尝试在sql server中根据日期时间和工作日编写一个查询,我的输出应该是这样的:

enter image description here

我的表格描述是:

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

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

这是我的原始数据

Data

1 个答案:

答案 0 :(得分:0)

所以,这是一个很长的镜头,但我通过以下方式解决了它:

我创建了一个table valued function,它将date作为参数,并在当天查找所有15-minute个时间间隔。 对于每一天,它会从00:00, to 00:15, 00:30升级到23: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表,工作日现在你已经在函数中了,但即使没有,也有DATENAME SQL Server中的函数,从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