我有一个跟踪版本历史记录的表。我需要记录显示第一个版本更改时间戳到最新版本。
编辑:添加了更多记录来说明我在寻找什么。 例如
id version timestamp
(123, 1.5, '2015-03-28 08:21:04'),
(123, 1.5, '2015-03-28 07:21:04'),
(123, 1.5, '2015-03-27 07:21:04'), <-- Latest version,first change for id 123
(123, 1.2, '2015-03-22 12:58:24'),
(123, 1.2, '2015-03-21 13:32:05'),
(123, 1.0, '2015-03-21 09:18:37'),
(123, 1.0, '2015-03-20 04:44:59'),
(234, 1.5, '2016-10-15 23:08:09'), <-- Latest version,first change for id 234
(345, 1.5, '2016-10-10 15:18:09'),
(345, 1.5, '2016-09-02 21:30:00'),
(345, 1.5, '2016-09-01 21:30:00'),
(345, 1.5, '2016-08-02 21:30:00'), <-- Latest version,first change for id 345
(345, 1.0, '2016-07-02 21:30:00')
预期输出
id version timestamp
(123, 1.5, '2015-03-27 07:21:04')
(234, 1.5, '2016-10-15 23:08:09')
(345, 1.5, '2016-08-02 21:30:00')
我能够通过使用临时表得到这个。我得到每个id和版本的min(dt_create)并将其存储在临时表中。然后我从这个表中获取每个id的最大日期然后加入它再次获得版本。有更好的方法吗?
create table #temp_version
(
id varchar(22) NOT NULL,
version varchar(50) NOT NULL,
dt_create datetime NOT null
)
insert into #temp_version
select id,version,min(dt_create) as dt_create
from [version_history] (nolock)
group by id,version
create table #temp_min_date
(
id varchar(22) NOT NULL,
dt_create datetime NOT null
)
insert into #temp_min_date
select id,max(dt_create)
from #temp_version
group by id
select a.id,a.version,a.dt_create
from #temp_version a
join #temp_date b on a.id = b.id and
a.dt_create=b.dt_create
drop table #temp_date
drop table #temp_version
答案 0 :(得分:1)
没有CTE或子查询的解决方案:
_ModerationStatus
答案 1 :(得分:1)
这是一个没有任何连接的查询:
select
id, [version], dt_create
from (
select
id,
[version],
rank() over (partition by id order by [version] desc, dt_create desc) as rnk,
min(dt_create) over (partition by id, [version]) as dt_create
from @history
) res
where
rnk = 1
整个查询包含您的测试数据:
declare @history table(id varchar(22), [version] varchar(50), dt_create datetime);
insert into @history(id, [version], dt_create) values
('123', '1.5', '2015-03-28 08:21:04'),
('123', '1.5', '2015-03-28 07:21:04'),
('123', '1.5', '2015-03-27 07:21:04'),
('123', '1.2', '2015-03-22 12:58:24'),
('123', '1.2', '2015-03-21 13:32:05'),
('123', '1.0', '2015-03-21 09:18:37'),
('123', '1.0', '2015-03-20 04:44:59'),
('234', '1.5', '2016-10-15 23:08:09'),
('345', '1.5', '2016-10-10 15:18:09'),
('345', '1.5', '2016-09-02 21:30:00'),
('345', '1.5', '2016-09-01 21:30:00'),
('345', '1.5', '2016-08-02 21:30:00'),
('345', '1.0', '2016-07-02 21:30:00')
select
id, [version], dt_create
from (
select
id,
[version],
rank() over (partition by id order by [version] desc, dt_create desc) as rnk,
min(dt_create) over (partition by id, [version]) as dt_create
from @history
) res
where
rnk = 1
答案 2 :(得分:0)
您可以使用带有子查询或CTE的窗口函数。请注意,在您的预期输出中,对于ID 123,您没有选择第一个实例...只选择具有最小TIME的实例,而不考虑日期。如果这是你真正想要的,那么你只需要按顺序使用时间部分。即(partition by id order by cast(timestamp as time))
select t.id, t.version, t.timestamp
from
YourTable t
inner join
(select
id,
version,
timestamp,
row_number() over (partition by id order by timestamp) as rn
from YourTable) x on x.id = t.id and x.timestamp = t.timestamp and x.version = t.version
where x.rn = 1
答案 3 :(得分:0)
尝试
create table #temp_version
(
id varchar(22) NOT NULL,
version varchar(50) NOT NULL,
dt_create datetime NOT null
)
insert into #temp_version values
(123, 1.5, '2015-03-28 08:21:04'),(123, 1.5, '2015-03-28 07:21:04'),(123, 1.5, '2015-03-27 07:21:04')
,(123, 1.0, '2015-03-21 12:58:24'),(123, 1.0, '2015-03-20 12:58:24'),(123, 1.2, '2015-03-22 12:58:24')
,(123, 1.2, '2015-03-21 12:58:24'),(234, 1.5, '2016-10-15 23:08:09'),(345, 1.5, '2016-10-10 15:18:09')
,(345, 1.5, '2016-09-02 21:30:00'),(345, 1.5, '2016-09-01 21:30:00'),(345, 1.5, '2016-08-02 21:30:00');
select top(1) with ties id, version, dt_create
from (
select *, lag(version) over(partition by id order by dt_create) prev
from #temp_version
) t
where version != prev or prev is null -- first change
-- recent version
order by row_number() over(partition by id order by dt_create desc);
-- or may be .. order by version .. depending on what is "recent"