繁体   English   中英

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

[英]Split date into month and year based on number of months passed in stored procedure into a temp table

我有一个存储过程,其中以数字为参数。 我用 where 子句做我的查询

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

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

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

例如:

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

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

如果我正确地跟随您,您可以在目标间隔内生成所有月份的开始,并将其与表格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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM