在包含 Order 信息的表(称为 Order )中,我们具有以下字段:
绑定时间以月为单位。
订单在其OrderDate
和DATEADD(mm, BindingTime, OrderDate)
之间被称为“有效”。
我想做的是按年份对订单进行分组,这样,如果订单在一年的第一天处于“活动状态”,则将其考虑在内。目的是计算每年的入站和出站订单。因此,查询结果将是COUNT
的订单和年份。而按年份,则是指该年第一天有效的订单数。
请记住,我们希望在结果中包含两个给定数字之间的所有年份。例如。如果2016年第一天没有活动订单,我们仍然希望在(0,2016)中有一行。
答案 0 :(得分:1)
我使用了递归CTE来生成年份范围,因此不会省略“零”年份
declare @YEAR1 as date = '20110101';
declare @YEAR2 as date = '20190101';
WITH YEARS AS (SELECT @YEAR1 y
UNION ALL
SELECT dateadd(year,1,y) FROM YEARS WHERE y < @YEAR2)
SELECT YEARS.y,count(0) YearStartActiveOrders FROM YourTable
CROSS JOIN YEARS
WHERE YEARS.y BETWEEN CAST(orderdate as date)
AND CAST(DATEADD(mm, BindingTime, OrderDate) as date)
GROUP BY Years.y
答案 1 :(得分:0)
好像您需要的是一个日期表(具有一年中所有天的列表),并让该表与您的分组数据(一年中的每天的活动订单数)结合在一起。
您可以使用this date table from Aaron Bertrand。我使用以下参数生成了#dim表,仅生成了两年数据(2015年,2016年):
DECLARE @StartDate DATE = '20150101', @NumberOfYears INT = 2;
然后您可以执行以下操作:
with ordertable as
(
select 1 as orderid, '20160101' as orderdate, 2 as bindingtime union all
select 2, '20160305', 3 union all
select 3, '20160305', 5 union all
select 4, '20150305', 5
)
select d.year, isnull(count(orderid), 0) nrActiveOrdersFirstDayOfYear
from #dim d
left join ordertable g on d.year = year(g.orderdate)
and g.orderdate = d.date
and d.FirstOfYear between g.orderdate and DATEADD(mm, g.bindingtime, OrderDate)
group by d.year
以我作为示例的样本数据,您将得到结果:
year nrActiveOrdersFirstDayOfYear
2015 0
2016 1
正在运行的演示here。