每年年初获取有效订单
Posted
技术标签:
【中文标题】每年年初获取有效订单【英文标题】:Get valid orders at the starting day of each year 【发布时间】:2018-07-13 08:50:41 【问题描述】:在包含订单信息的表格中(称为订单),我们有以下字段:
-
OrderId int
订单日期 日期
绑定时间 int
绑定时间以月为单位。
在OrderDate
和DATEADD(mm, BindingTime, OrderDate)
之间的订单称为“活动”。
我想做的是按年份对订单进行分组,这样如果订单在一年的第一天“活跃”,就会被考虑在内。目的是计算每年的入站和出站订单。所以查询结果将是订单和年份的COUNT
。年份指的是当年第一天活跃的订单数。
请注意,我们希望在结果中包含两个给定数字之间的所有年份。例如。如果 2016 年的第一天没有有效订单,我们仍然希望为 (0, 2016) 保留一行。
【问题讨论】:
你知道演习...请示例数据和预期输出 您是只想计算一年中第一天的活跃订单,还是一年中某个时间活跃的订单?在第二种情况下,如果它们跨越一年开始,它们会被计算两次吗? @Cato 只有那些在一年的第一天活跃的人。活跃是一个间隔。因此,如果该间隔包括一年的一月一日,则应将其考虑在内。如果有效订单跨越多年,则应包括第一天在该区间内的所有年份。 这就是我希望在下面所做的 【参考方案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
【讨论】:
让我检查一下结果再回来找你。看起来正确。【参考方案2】:您似乎需要一个日期表(包含每年所有日期的列表),然后将您的分组数据(活跃订单数,一年中的每一天)加入该表。
您可以使用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。
【讨论】:
以上是关于每年年初获取有效订单的主要内容,如果未能解决你的问题,请参考以下文章
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?