根据另一个 table 填充 ID
Populate Id's Based on another table
我有以下 Table:
以上示例数据如下:
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
注意开始日期,其中 idYear = 1
是该月的月底。我以这种方式提供了样本数据,因为它正是我实际 table...
中的情况
然后我使用此脚本为这些月之间的所有期间生成每个月的月末:
;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
然后我用我的虚拟 table 加入 cte
,如下所示:
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
以上给出了以下结果:
我该如何操作使其看起来如下所示:
我已经尝试了 rank
、ntile
和 row_number
,但是 none 给出了我需要的结果...
非常感谢您的帮助!
编辑
我已将上面的 select
更改为以下内容:
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
但是可以看出,它看起来不像我预期的结果:
您可以尝试通过连接 YEAR(@years.dYearStartDate) 和 YEAR(month.EndOfMonth) 从 @years table 获取每年的信息,如下所示:
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
向我的 table 添加一个 End Date
,这很有效。
话虽如此,我可以查询这些日期之间的 idYear
,如下所示:
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
结果如下(最后一列是我需要的结果):
我有以下 Table:
以上示例数据如下:
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
注意开始日期,其中 idYear = 1
是该月的月底。我以这种方式提供了样本数据,因为它正是我实际 table...
然后我使用此脚本为这些月之间的所有期间生成每个月的月末:
;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
然后我用我的虚拟 table 加入 cte
,如下所示:
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
以上给出了以下结果:
我该如何操作使其看起来如下所示:
我已经尝试了 rank
、ntile
和 row_number
,但是 none 给出了我需要的结果...
非常感谢您的帮助!
编辑
我已将上面的 select
更改为以下内容:
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
但是可以看出,它看起来不像我预期的结果:
您可以尝试通过连接 YEAR(@years.dYearStartDate) 和 YEAR(month.EndOfMonth) 从 @years table 获取每年的信息,如下所示:
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
向我的 table 添加一个 End Date
,这很有效。
话虽如此,我可以查询这些日期之间的 idYear
,如下所示:
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
结果如下(最后一列是我需要的结果):