sql server中两个日期之间的月份(每个日期的开始日期和结束日期在sql server中的结束日期)可以为空
我想得到两个日期之间的月份,包括开始日期和结束日期。假设我输入的起始日期为2019年6月7日,结束日期为2019年9月18日,我想分别列出两者之间的月份及其开始和结束日期。请建议我如何实现。此外,如果Utc结束日期为空,则应自动将日期拆分为当前日期,即19/09/19 输入表BusinessGoal:sql server中两个日期之间的月份(每个日期的开始日期和结束日期在sql server中的结束日期)可以为空,sql,sql-server,Sql,Sql Server,我想得到两个日期之间的月份,包括开始日期和结束日期。假设我输入的起始日期为2019年6月7日,结束日期为2019年9月18日,我想分别列出两者之间的月份及其开始和结束日期。请建议我如何实现。此外,如果Utc结束日期为空,则应自动将日期拆分为当前日期,即19/09/19 输入表BusinessGoal: BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Curre
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business C Year CommittedTransactionFee 18000 05/07/19 00:00:00 19/09/19 00:00:00 USD
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business C 2019-07 - 2019-08 CommittedTransactionFee 18000 05/07/2019 00:00:00 05/08/2019 00:00:00 USD
Business C 2019-08 - 2019-09 CommittedTransactionFee 18000 05/08/2019 00:00:00 05/09/2019 00:00:00 USD
Business C 2019-09 - 2019-10 CommittedTransactionFee 18000 05/09/2019 00:00:00 05/10/2019 00:00:00 USD
输出表业务目标:
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business C Year CommittedTransactionFee 18000 05/07/19 00:00:00 19/09/19 00:00:00 USD
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business C 2019-07 - 2019-08 CommittedTransactionFee 18000 05/07/2019 00:00:00 05/08/2019 00:00:00 USD
Business C 2019-08 - 2019-09 CommittedTransactionFee 18000 05/08/2019 00:00:00 05/09/2019 00:00:00 USD
Business C 2019-09 - 2019-10 CommittedTransactionFee 18000 05/09/2019 00:00:00 05/10/2019 00:00:00 USD
我已经写了一个查询,它根据年度分割日期,即BusinessGoal.Period='Year'
declare @BusinessGoal table
(BusinessRefId varchar(50),
Period varchar(50),
GoalType varchar(100),
Amount money,
StartDateUtc datetime,
EndDateUtc datetime,
Currency varchar(10));
insert into @BusinessGoal values
('Business A', 'Year', 'CommittedTransactionFee', 45000, '2019-06-07 00:00:00', NULL, 'USD'),
('Business B', 'Year', 'CommittedTransactionFee', 18000, '2017-06-07 00:00:00', NULL, 'USD'),
('Business E', 'Year', 'CommittedTransactionFee', 5000 , '2019-04-01 00:00:00', '2019-08-01 00:00:00', 'USD');
select BusinessRefId
, cast(ys.y as varchar(4)) + '-' + cast(ys.y + 1 as varchar(4)) Period
, GoalType, Amount
, dateadd(year, nmbs.n, tbl.StartDateUtc) StartDateUtc
, case when ys.NextDate > tbl.EndDateUtc then tbl.EndDateUtc else ys.NextDate end EndDateUtc
, Currency
from @BusinessGoal tbl
join
(values (0),(1),(2)
) nmbs(n)
on dateadd(year, nmbs.n, tbl.StartDateUtc) <= getdate()
and (EndDateUtc is null or EndDateUtc >= datefromparts(Year(tbl.StartDateUtc) + nmbs.n + 1, 1, 1))
cross apply (select Year(tbl.StartDateUtc) + nmbs.n y, dateadd(year, nmbs.n + 1,tbl.StartDateUtc) NextDate) ys
我必须通过对BusinessGoal表期间列(即
如果BusinessGoal.Period='Year',如果BusinessGoal.Period='Month' 这是如何编写Caius Jard在评论中提出的递归CTE:
-- Create a Test Table
select '2019-07-05' as StartDateUtc, '2019-09-19' as EndDateUtc
into #test;
-- Recursive CTE that returns the months between StartDateUtc and EndDateUtc
with months as (
-- initial values of the recursive CTE
select datefromparts(year(StartDateUtc), month(StartDateUtc), 1) as StartPeriod,
dateadd(month, 1, datefromparts(year(StartDateUtc), month(StartDateUtc), 1)) as EndPeriod,
t.StartDateUtc, t.EndDateUtc
from #test t
union all
-- we recursively add 1 month until we reach EndDateUtc
select dateadd(month, 1, StartPeriod) as StartPeriod,
dateadd(month, 1, EndPeriod) as EndPeriod,
months.StartDateUtc, months.EndDateUtc
from months
where dateadd(month, 1, StartPeriod) <= coalesce(EndDateUtc, StartDateUtc) -- If EndDateUtc is null then we use StartDateUtc, so only the first month is returned
)
select * from months;
-- Drop Test Table
drop table #test;
创建一个递归CTE,该CTE将生成从0开始的递增整数序列,将其加入到数据中,并将递增整数添加到起始日期,以月为间隔。coalescendDate,getutcdate使结束日期为当前日期(如果为空)。使用where子句查找所需日期之间的行。这几乎就是你所拥有的,除了它每隔几个月而不是几年工作,并且产生更多rows@CaiusJard我必须将其集成到我在上述问题中提到的现有查询中。好的,同样,也要做月份表单——制作你已经检查过的where子句,看看是否传入了“年”,然后做where子句或另一个类似的where子句,看看是否传入了月份,dateaddmonths而不是years。您可能会发现执行两个查询比较容易,一个查询执行年份,并且只在business goal=year的位置工作,然后合并另一个查询,该查询只执行月份和businessgoal=months@CaiusJard我不知道如何创建递归CTE。