我必须生成一个SQL查询的结果集,该结果集应与以下内容匹配,但让我解释输入和输出:
我有一个名为Orders
的表,这个表在某些时间有几个小时的订单,然后,我被要求提供一个结果集,该结果集应该可以获得两个日期之间的所有日期(即2017-10-01和2017-10-07),每天24小时,即使那天或那个小时没有订单,但它应该以{{1}}值出现。
0
因此,上述结果集应该包含给定两个日期之间的每一天,并且每天应该全部24小时,无论当天有订单和小时相同(无论是否有订单)
答案 0 :(得分:1)
最简单的方法是使用临时表或表变量来填充所需的结果集,然后计算每行的订单数。
declare @Date1 date = '2017-10-01';
declare @Date2 date = '2017-10-07';
declare @Hour int;
declare @Period table (Day Date, Hour Time);
while @Date1 <= @Date2
begin
set @Hour = 0;
while @Hour < 24
begin
insert into @Period (Day, Hour) values (@Date1, TimeFromParts(@Hour,0,0,0,0));
set @Hour = @Hour + 1;
end
set @Date1 = DateAdd(Day, 1, @Date1);
end
select Day, Hour,
(select count(*)
from Orders
where Orders.Day = Period.Day and Orders.Hour = Period.Hour) as TotalOrders
from @Period as Period;
答案 1 :(得分:1)
我更喜欢使用计数表而不是使用循环。性能要好得多。我保持对我的系统的统计,就像这样的观点。
create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO
现在我们有了计数表,我们可以使用一些基本的数学来获得所需的输出。这些方面的东西。
declare @Date1 datetime = '2017-10-01';
declare @Date2 datetime = '2017-10-07';
select Day = convert(date, DATEADD(hour, t.N, @Date1))
, Hour = t.N - 1
, TotalOrders = COUNT(o.OrderID)
from cteTally t
left join Orders o on o.OrderDate = DATEADD(hour, t.N, @Date1)
where t.N <= DATEDIFF(hour, @Date1, @Date2)
group by DATEDIFF(hour, @Date1, @Date2)
, t.N
答案 2 :(得分:1)
我是使用嵌套CTE完成的:
DECLARE @MinDate DATE = '20171001',
@MaxDate DATE = '20171006';
;WITH INNER_CTE as(
SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b) ,
OUTER_CTE as (
select * from INNER_CTE
cross apply (
SELECT TOP (24) n = ROW_NUMBER() OVER (ORDER BY [object_id]) -1
FROM sys.all_objects ORDER BY n)) t4
)
select t1.Date, t1.n [Hour], ISNULL(t2.TotalORders,0) TotalOrders from
OUTER_CTE t1
LEFT JOIN orders t2 on t1.Date = t2.[Day] and t1.n = t2.[Hour]
关于使用查询生成序列的好读物:https://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1