我必须有一张跟踪某些设备版本的表格。该表用于跟踪任何版本升级,并且设备在一天中的不同时间ping它们的版本。最近,我注意到如果一个用户使用/注册另一个设备,那么对于同一个用户,该表将在同一天ping多个版本。遗憾的是,我无法更改此表的基础架构或将版本ping收集到不同的表集中的逻辑。
现在问题是当其中一个设备发生版本升级时,该表将显示给定日期的两个不同版本,这是正确的,但是由于用户有另一个设备,我也获得该设备的版本。
我的目标是过滤掉任何有超过1个设备的ID。现在在下面的示例中假设9.X是Android设备,所有1.X版本都是ios。在这种情况下,123有两个设备,我需要从数据集中删除123以进行进一步分析。我需要跟踪合法升级,所以在下面的情况下,只有234和345是1台设备的合法升级。虽然123的第一台设备将ios从1.6升级到1.7但我不能在分析中包含它因为123 id有另一台设备android 9.0。
123 1.7 2017-08-11 22:57:54.307
123 9.0 2017-08-11 21:37:54.307 <-- 123 second device version
123 1.7 2017-08-11 20:27:54.307
123 1.7 2017-08-11 19:17:54.307 <-- 123 first device version upgrade
123 1.6 2017-08-11 18:47:54.307
123 1.6 2017-08-11 17:37:54.307
123 9.0 2017-08-11 16:57:54.307 <-- 123 signed up with a new device
123 1.6 2017-08-11 15:17:54.307 <-- 123 first device version
234 1.7 2017-08-11 22:47:54.307
234 1.7 2017-08-11 21:47:54.307 <-- 234 first device version upgrade
234 1.5 2017-08-11 20:47:54.307
234 1.5 2017-08-11 19:47:54.307
234 1.5 2017-08-11 18:47:54.307 <-- 234 first device version
345 1.8 2017-08-11 22:47:54.307
345 1.8 2017-08-11 21:47:54.307 <-- 345 first device version upgrade
345 1.4 2017-08-11 20:47:54.307
345 1.4 2017-08-11 19:47:54.307
345 1.4 2017-08-11 18:47:54.307 <-- 345 first device version
我的脚本为我提供了正确的升级,但没有使用多于1个设备过滤那些ID。我需要在第一步中执行此操作,以便在最终数据集中不包含123。
;with device_versions as
(
select id,
ver,
row_no = ROW_NUMBER() OVER (partition by id order by MAX(dt_create) desc),
dt_create = MAX(dt_create),
case
when ver like '1.0%' then 'ios'
else 'android'
end device_name
from dbo.version_history
group by id, ver
)
select *,ios_row_no = ROW_NUMBER() over (partition by id order by min(dt_create) asc)
into #temp
from device_versions
where id in (select id from device_versions where row_no > 1 )
group by id,ver,row_no,dt_create,device_name
order by row_no
select id,ver,row_no,dt_create,device_name,ios_row_no
into #temp_final
from #temp a
where device_name='android' and
ios_row_no = (select MAX(ios_row_no) from #temp b where a.id=b.id
and device_name='android')
select a.id, dt_create = MIN(a.dt_create)
from #temp_final b
JOIN dbo.version_history a
ON a.id = b.id
AND a.dt_create > b.dt_create
where device_name ='android'
group by a.id
union
select a.id, dt_create = MIN(a.dt_create)
from #temp b
JOIN dbo.version_history a
ON a.id = b.id
AND a.dt_create > b.dt_create
where row_no = 2 and a.id not in (select id from #temp where device_name like 'ios')
group by a.id
union
select a.id, MIN(a.dt_create)
from #temp b
JOIN dbo.version_history a
ON a.id = b.id
where a.id not in (select id from #temp where device_name like 'android')
group by a.id
drop table #temp
drop table #temp_final
当前输出 - 我需要在第一步中过滤掉123
123
234
345
预期输出 - 我的脚本适用于具有单个设备和合法升级的所有ID。
234
345
答案 0 :(得分:1)
使用LEAD()。
<强> 1)强>
select id,ver,lead(id,1) over (order by id,dt_create desc) as next_id,lead(ver,1) over (order by id,dt_create desc ) as next_ver,dt_create
into #temp1
from Z_version
order by id,dt_create desc
id ver next_id next_ver dt_create
123 1.7 123 9.0 2017-08-11 22:57:54.307
123 9.0 123 1.7 2017-08-11 21:37:54.307
123 1.7 123 1.7 2017-08-11 20:27:54.307
123 1.7 123 1.6 2017-08-11 19:17:54.307
123 1.6 123 1.6 2017-08-11 18:47:54.307
123 1.6 123 9.0 2017-08-11 17:37:54.307
123 9.0 123 1.6 2017-08-11 16:57:54.307
123 1.6 123 1.6 2017-08-11 15:17:54.307
123 1.6 123 1.6 2017-07-11 22:57:54.307
123 1.6 123 1.6 2017-07-11 21:37:54.307
123 1.6 123 1.6 2017-07-11 20:27:54.307
123 1.6 234 1.7 2017-07-11 19:17:54.307
234 1.7 234 1.7 2017-08-11 22:47:54.307
234 1.7 234 1.5 2017-08-11 22:47:54.307
234 1.5 234 1.5 2017-08-11 20:47:54.307
234 1.5 234 1.5 2017-08-11 19:47:54.307
234 1.5 234 1.5 2017-08-11 18:47:54.307
234 1.5 234 1.3 2017-07-11 22:47:54.307
234 1.3 234 1.3 2017-07-11 20:47:54.307
234 1.3 234 1.3 2017-07-11 19:47:54.307
234 1.3 345 1.8 2017-07-11 18:47:54.307
345 1.8 345 1.8 2017-08-11 22:47:54.307
345 1.8 345 1.4 2017-08-11 21:47:54.307
345 1.4 345 1.4 2017-08-11 20:47:54.307
345 1.4 345 1.4 2017-08-11 19:47:54.307
345 1.4 345 1.4 2017-08-11 18:47:54.307
345 1.4 NULL NULL 2017-07-11 06:34:35.307
<强> 2)强>
select * into #temp2 from #temp1 where ver<>next_ver and id=next_id
id ver next_id next_ver dt_create
123 1.7 123 9.0 2017-08-11 22:57:54.307
123 9.0 123 1.7 2017-08-11 21:37:54.307
123 1.7 123 1.6 2017-08-11 19:17:54.307
123 1.6 123 9.0 2017-08-11 17:37:54.307
123 9.0 123 1.6 2017-08-11 16:57:54.307
234 1.7 234 1.5 2017-08-11 22:47:54.307
234 1.5 234 1.3 2017-07-11 22:47:54.307
345 1.8 345 1.4 2017-08-11 21:47:54.307
第3)强>
select id,convert(varchar(12),dt_create,112) as each_day,count(ver) as ver_count into #temp3 from #temp2
group by id,convert(varchar(12),dt_create,112) order by id
id each_day ver_count
123 20170811 5
234 20170711 1
234 20170811 1
345 20170811 1
<强> 4)强>
select id,max(ver_count) max_count into #temp4 from #temp3 group by id
id max_count
123 5
234 1
345 1
<强> 5)强>
select id,max_count from #temp4 where max_count < 2
id max_count
234 1
345 1
<强> 6)强>
drop table #temp1
drop table #temp2
drop table #temp3
drop table #temp4
答案 1 :(得分:0)
如果我理解你的问题,也许这会简化它。
示例强>
Select Top 1 With Ties *
From YourTable
Where ID not in (Select ID From YourTable Group By ID having floor(min(ver))<>floor(max(ver)))
Order By Row_Number() over (Partition by id order by dt_create desc)
<强>返回强>
id ver dt_create
234 1.7 2017-08-11 22:47:54.307
345 1.8 2017-08-11 22:47:54.307
编辑 - 按ID划分,日期
;with cte as (
Select *
,VerCnt = sum(1) over (partition by id,cast(dt_create as date))
,VerMin = min(ver) over (partition by id,cast(dt_create as date))
,VerMax = max(ver) over (partition by id,cast(dt_create as date))
From @YourTable
)
Select top 1 with ties
id,ver,dt_create
From cte
Where floor(VerMin)=floor(VerMax)
and VerCnt>1
Order By Row_Number() over (Partition by id order by dt_create desc)