我正在尝试在sql server中根据日期时间和工作日编写一个查询,我的输出应该是这样的:
我的表格描述是:
**Branch**(DateKey integer,
BranchName varchar2(20),
TransactionDate datetime,
OrderCount integer)
**Date**(DateKey integer PrimaryKey,
DayNameofWeek varchar2(15))
这是我的原始数据
答案 0 :(得分:0)
所以,这是一个很长的镜头,但我通过以下方式解决了它:
我创建了一个table valued function
,它将date
作为参数,并在当天查找所有15-minute
个时间间隔。
对于每一天,它会从00:00, to 00:15, 00:30
升级到23:30, 23:45
和23:59
。它还返回每个时间间隔start time
和end 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
。