在一个结果行中选择具有给定时间间隔的 id history 的行
selecting rows with id history for a given time interval in one result row
A table StatusHistory
包含:
ID Status DtSince DtUntil
2415891 0 20200816 20200917
2415891 4 20200917 NULL
2415892 0 20200904 20200905
2415892 4 20200905 NULL
我需要 select 每个 id 的每个月初和月底的状态。
用户将输入所需的日期。例如:
用户输入 --> @Month = '202009'
select 语句必须 return dates 20200901 and 20201001
的状态
对于新的且 dtSince>20200901 的记录,它应该 return 2415892
的活动 row.For 示例它应该 return 4
。
所以@Month = 202009 的结果集应该是:
Id BeginningOfMonth_status EndOfMonth_status
2415891 0 4
2415892 4 4
这是我的解决方案
select * from
(
select * from
(
select *, ROW_NUMBER() over (partition by id order by dtSince desc) r from
dbo.StatusHistory
where DtUntil is null or (DtUntil <20201001and dtSince>=20200901) --2432290
)x
where x.r=1
)s1
inner join
(
select * from
(
select *, ROW_NUMBER() over (partition by id order by dtSince desc) r from
dbo.StatusHistory
where DtUntil is null or (DtUntil <20201001and dtSince>=20200901) --2432290
)x
where x.r=2
)s2
on s1.id = s2.id
问题:
1)有比我的代码更简单的吗?
2) 以上,我没有涵盖 For records that are new and have dtSince>20200901
要求
嗯。 . .您可以使用 where
子句获取涵盖特定月份的所有行。然后使用row_number()
枚举行和条件聚合:
select id,
max(case when seqnum_asc = 1 then status end) as beginning_of_month,
max(case when seqnum_desc = 1 then status end) as end_of_month
from (select t.*,
row_nunber() over (partition by id order by dtsince) as seqnum_asc,
row_nunber() over (partition by id order by dtsince desc) as seqnum_desc
from t
where dtsince < dateadd(month, 1, convert(date, @Month + '01'))) and
(dtuntil >= convert(date, @Month + '01') or dtuntil is null)
) t
group by id
A table StatusHistory
包含:
ID Status DtSince DtUntil
2415891 0 20200816 20200917
2415891 4 20200917 NULL
2415892 0 20200904 20200905
2415892 4 20200905 NULL
我需要 select 每个 id 的每个月初和月底的状态。 用户将输入所需的日期。例如:
用户输入 --> @Month = '202009'
select 语句必须 return dates 20200901 and 20201001
对于新的且 dtSince>20200901 的记录,它应该 return 2415892
的活动 row.For 示例它应该 return 4
。
所以@Month = 202009 的结果集应该是:
Id BeginningOfMonth_status EndOfMonth_status
2415891 0 4
2415892 4 4
这是我的解决方案
select * from
(
select * from
(
select *, ROW_NUMBER() over (partition by id order by dtSince desc) r from
dbo.StatusHistory
where DtUntil is null or (DtUntil <20201001and dtSince>=20200901) --2432290
)x
where x.r=1
)s1
inner join
(
select * from
(
select *, ROW_NUMBER() over (partition by id order by dtSince desc) r from
dbo.StatusHistory
where DtUntil is null or (DtUntil <20201001and dtSince>=20200901) --2432290
)x
where x.r=2
)s2
on s1.id = s2.id
问题:
1)有比我的代码更简单的吗?
2) 以上,我没有涵盖 For records that are new and have dtSince>20200901
要求
嗯。 . .您可以使用 where
子句获取涵盖特定月份的所有行。然后使用row_number()
枚举行和条件聚合:
select id,
max(case when seqnum_asc = 1 then status end) as beginning_of_month,
max(case when seqnum_desc = 1 then status end) as end_of_month
from (select t.*,
row_nunber() over (partition by id order by dtsince) as seqnum_asc,
row_nunber() over (partition by id order by dtsince desc) as seqnum_desc
from t
where dtsince < dateadd(month, 1, convert(date, @Month + '01'))) and
(dtuntil >= convert(date, @Month + '01') or dtuntil is null)
) t
group by id