Tsql 基于另一个表填充Id

Tsql 基于另一个表填充Id,tsql,sql-server-2017,Tsql,Sql Server 2017,我有下表: 上述示例数据如下所示: declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime) insert into @years (cYearDescription,dYearStartDate) values ('Year 1','2014-08-31') , ('Year 2','2015-07-01') , (

我有下表:

上述示例数据如下所示:

declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime)

insert into @years (cYearDescription,dYearStartDate) values
    ('Year 1','2014-08-31')
,   ('Year 2','2015-07-01')
,   ('Year 3','2016-07-01')
,   ('Year 4','2017-07-01')
,   ('Year 5','2018-07-01')
,   ('Year 6','2019-07-01')

select
*
from    @years
declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime)

insert into @years (cYearDescription,dYearStartDate) values
    ('Year 1','2014-08-31')
,   ('Year 2','2015-07-01')
,   ('Year 3','2016-07-01')
,   ('Year 4','2017-07-01')
,   ('Year 5','2018-07-01')
,   ('Year 6','2019-07-01')


;with cte as
(
select  dateadd(day, nbr - 1, (select min(dYearStartDate) from @years)) CalendarDate
from    ( select    row_number() over ( order by c.object_id ) as nbr
          from      sys.columns c
        ) nbrs
where   nbr - 1 <= datediff(day, (select min(dYearStartDate) from @years), (select max(dYearStartDate) from @years))
)
,   months as (
select
eomonth(CalendarDate)   EndOfMonth
from    cte
group by eomonth(CalendarDate)
)

select
*
from    months m
left join @years y  on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
select
*
,   isnull(idYear,lag(idYear) over (order by EndOfMonth))   idYear
,   (select idYear from @years where year(dYearStartDate) = year(EndOfMonth))   idYear
from    months m
left join @years y  on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
select
*
,       iif(idYear is null,(select idYear from LeadDateAdded where EndOfMonth between dYearStartDate and dYearEndDate),idYear)  idYear
from    months m
left join LeadDateAdded y   on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
请注意,其中idYear=1的开始日期是该月的结束日期。我以这种方式提供了示例数据,因为它在我的实际表中是完全一样的

然后,我使用以下脚本为这两个月之间的所有时段生成每个月末:

;with cte as
(
select  dateadd(day, nbr - 1, (select min(dYearStartDate) from @years)) CalendarDate
from    ( select    row_number() over ( order by c.object_id ) as nbr
          from      sys.columns c
        ) nbrs
where   nbr - 1 <= datediff(day, (select min(dYearStartDate) from @years), (select max(dYearStartDate) from @years))
)
,   months as (
select
eomonth(CalendarDate)   EndOfMonth
from    cte
group by eomonth(CalendarDate)
)

select
*
from    months
以上给出了以下结果:

我如何操作它,使其看起来如下所示:

我试过排名、分数和行数,但没有一个能给出我需要的结果

非常感谢您的帮助

编辑

我已将上面的选择更改为以下内容:

declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime)

insert into @years (cYearDescription,dYearStartDate) values
    ('Year 1','2014-08-31')
,   ('Year 2','2015-07-01')
,   ('Year 3','2016-07-01')
,   ('Year 4','2017-07-01')
,   ('Year 5','2018-07-01')
,   ('Year 6','2019-07-01')

select
*
from    @years
declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime)

insert into @years (cYearDescription,dYearStartDate) values
    ('Year 1','2014-08-31')
,   ('Year 2','2015-07-01')
,   ('Year 3','2016-07-01')
,   ('Year 4','2017-07-01')
,   ('Year 5','2018-07-01')
,   ('Year 6','2019-07-01')


;with cte as
(
select  dateadd(day, nbr - 1, (select min(dYearStartDate) from @years)) CalendarDate
from    ( select    row_number() over ( order by c.object_id ) as nbr
          from      sys.columns c
        ) nbrs
where   nbr - 1 <= datediff(day, (select min(dYearStartDate) from @years), (select max(dYearStartDate) from @years))
)
,   months as (
select
eomonth(CalendarDate)   EndOfMonth
from    cte
group by eomonth(CalendarDate)
)

select
*
from    months m
left join @years y  on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
select
*
,   isnull(idYear,lag(idYear) over (order by EndOfMonth))   idYear
,   (select idYear from @years where year(dYearStartDate) = year(EndOfMonth))   idYear
from    months m
left join @years y  on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
select
*
,       iif(idYear is null,(select idYear from LeadDateAdded where EndOfMonth between dYearStartDate and dYearEndDate),idYear)  idYear
from    months m
left join LeadDateAdded y   on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
但可以看出,这与我的预期结果不符:


您可以尝试通过加入@years表来获取每年的信息YEAR@years.dYearStartDate和YEARmonth.EndOfMonth,就像这样:

select a.EndOfMonth, b.idYear, b.cYearDescription, b.dYearStartDate
 from (
    select year(m.EndOfMonth) curYear, *
       from months m
     left join @years y  
       on  eomonth(dYearStartDate) = EndOfMonth) a
   inner join (select year(dYearStartDate) curYear, * from @years) b
     on a.curYear = b.curYear
   order by EndOfMonth

我能解决这个问题的唯一方法是使用LEAD在我的表中添加一个结束日期,这很有效

鉴于上述情况,我可以通过以下方式查询这些日期之间的时间:

declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime)

insert into @years (cYearDescription,dYearStartDate) values
    ('Year 1','2014-08-31')
,   ('Year 2','2015-07-01')
,   ('Year 3','2016-07-01')
,   ('Year 4','2017-07-01')
,   ('Year 5','2018-07-01')
,   ('Year 6','2019-07-01')

select
*
from    @years
declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime)

insert into @years (cYearDescription,dYearStartDate) values
    ('Year 1','2014-08-31')
,   ('Year 2','2015-07-01')
,   ('Year 3','2016-07-01')
,   ('Year 4','2017-07-01')
,   ('Year 5','2018-07-01')
,   ('Year 6','2019-07-01')


;with cte as
(
select  dateadd(day, nbr - 1, (select min(dYearStartDate) from @years)) CalendarDate
from    ( select    row_number() over ( order by c.object_id ) as nbr
          from      sys.columns c
        ) nbrs
where   nbr - 1 <= datediff(day, (select min(dYearStartDate) from @years), (select max(dYearStartDate) from @years))
)
,   months as (
select
eomonth(CalendarDate)   EndOfMonth
from    cte
group by eomonth(CalendarDate)
)

select
*
from    months m
left join @years y  on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
select
*
,   isnull(idYear,lag(idYear) over (order by EndOfMonth))   idYear
,   (select idYear from @years where year(dYearStartDate) = year(EndOfMonth))   idYear
from    months m
left join @years y  on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
select
*
,       iif(idYear is null,(select idYear from LeadDateAdded where EndOfMonth between dYearStartDate and dYearEndDate),idYear)  idYear
from    months m
left join LeadDateAdded y   on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
完整的最终代码如下所示:

declare @years table (idYear int primary key identity, cYearDescription varchar(20), dYearStartDate datetime)

insert into @years (cYearDescription,dYearStartDate) values
    ('Year 1','2014-08-31')
,   ('Year 2','2015-07-01')
,   ('Year 3','2016-07-01')
,   ('Year 4','2017-07-01')
,   ('Year 5','2018-07-01')
,   ('Year 6','2019-07-01')
,   ('Year 7','2020-07-01')


;with cte as
(
select  dateadd(day, nbr - 1, (select min(dYearStartDate) from @years)) CalendarDate
from    ( select    row_number() over ( order by c.object_id ) as nbr
          from      sys.columns c
        ) nbrs
where   nbr - 1 <= datediff(day, (select min(dYearStartDate) from @years), (select max(dYearStartDate) from @years))
)
,   months as (
select
eomonth(CalendarDate)   EndOfMonth
from    cte
group by eomonth(CalendarDate)
)
,   Years as (
select
    idYear
,   cYearDescription
,   dYearStartDate
,   cast(lead(eomonth(dYearStartDate)) over (order by idYear) as datetime)  dYearEndDate
from    @years
)

select
*
,       iif(idYear is null,(select idYear from Years where EndOfMonth between dYearStartDate and dYearEndDate),idYear)  idYear
from    months m
left join Years y   on  eomonth(dYearStartDate) = EndOfMonth
order by EndOfMonth
结果如下:最后一列是我需要的结果:


很高兴您将示例数据发布为DDL+DML,但是这些图像无助于理解这个问题,它们只会让问题变得更难,至少对我来说是这样。在当前输出旁边清晰地显示所需输出的文本将有很大帮助。抱歉@ZoharPeled,我需要idYear,每个月重复一次,但从我的编辑中可以看出,我的尝试给了我错误的idYear最后一列-希望能更好地解释它…?即从第1行到第11行,我需要idYear为1,从第12行到第23行,我需要idYear为2,等等。不幸的是,这不起作用,因为根据我的@year表,我的周期从2014年8月开始,到2015年6月结束,这是我面临的困境,这个特定时间的周期需要为1。对于第2阶段,我的开始日期是2015年7月,结束日期是2015年6月,应该是第2阶段的开始日期,以此类推。