2017-09-29 64 views
1

我必須有一個表來跟蹤某些設備的版本。該表用於跟蹤任何版本升級,並且設備在一天中的不同時間對其版本進行ping。最近,我注意到如果一個用戶使用/註冊另一個設備,那麼對於同一個用戶,該表將在同一天有多個版本的ping。不幸的是,我無法更改此表的底層模式或邏輯將版本ping收集到不同的表中。計算連續行之間的變化值並過濾SQL Server

現在的問題是當設備發生版本升級時,表格會顯示給定日期的兩個不同版本,這是正確的,但是由於用戶有另一個設備,我也獲得了該設備的版本。

我的目標是過濾掉任何有一個以上設備的ID。現在在下面的例子可以說9.X是Android設備,所有1.X版本是IOS。在這種情況下,ID,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個device.I過濾那些IDS需要做到這一點的第一步,讓我不包括在最終的數據集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  

回答

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

幹得好!對不起,我被拉走了+1 –

+0

謝謝,與你討論幫助我達成了解決方案。 –

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) 
+0

因爲如果存在多於2個版本給定的一天,我可以假設該id具有另一設備即1做了升級,然後有另一種。第二種方式我可以確定是在給定的一天我得到多個版本,如x,y,x,y ,x,y。第二個問題是設備進行升級時,我一定會有x,y版本的組合。我只需要在第一步中用多於1個設備過濾掉用戶。 –

+0

@inquisitive_mind啊。我會更多一點 –

+0

謝謝,也許如果我計算每個id版本的pings不同的次數,我可以得到123 filtered.Like在上面的情況下,在給定的id 123的連續行之間有5個版本的組合日.1.6-9.0,9.0-1.6,1.6-1.7,1.7-9.0和最後9.0-1.7。可能是版本上的滯後/潛在的組合? –