根据存储过程中传递到临时表中的月份数,将日期拆分为月份和年份



我有一个存储过程,其中将数字作为参数。我用类似的where子句进行查询

select salesrepid, month(salesdate), year(salesdate), salespercentage 
from SalesRecords
where salesdate >= DATEADD(month, -@NumberOfMonths, getdate())

例如,如果@NumberOFmonths passed=3,并且基于今天的日期,

在我的结果集中,应该是9月9日、10月10日和11月11日。我的查询带来了它,但请求是我需要为那些一个月内没有值的销售代表返回null,

例如:

salerepid     month      year     salespercentage
232          9         2020       80%
232          10        2020       null
232          11        2020       90%

我怎样才能做到这一点?现在,查询只返回两条记录,并且没有返回十月数据,因为没有值,但我希望它返回零值的十月。

如果我正确地遵循您的指示,您可以在目标间隔内生成所有月初,并使用表生成cross join以生成所有可能的组合。然后你可以带上left join:

with all_dates as (
select datefromparts(year(getdate()), month(getdate()), 1) salesdate, 0 lvl
union all
select dateadd(month, - lvl - 1, salesdate), lvl + 1
from all_dates 
where lvl < @NumberOfMonths
)
select r.salesrepid, d.salesdate , s.salespercentage
from all_dates d
cross join (select distinct salesrepid from salesrecords) r
left join salesrecord s
on  s.salesrepid = r.salesrepid
and s.salesdate >= d.salesdate 
and s.salesdate <  dateadd(month, 1, d.salesdate )

您最初的查询和结果意味着每个销售代表和月份最多有一条记录,因此这在相同的假设下起作用。如果不是这样(这在某种程度上更有意义(,则需要在外部查询中进行聚合。

声明@numberofmonths int=3;

with all_dates as (
select datefromparts(year(getdate()), month(getdate()), 1) dt, 0 lvl
union all
select dateadd(month, - lvl - 1, dt), lvl + 1
from all_dates 
where lvl < 3
)
select * from all_dates
This gives me following result:
2020-11-01  0
2020-10-01  1
2020-08-01  2
2020-05-01  3
I want only:
2020-11-01  0
2020-10-01  1
2020-09-01  2

最新更新