2017-03-29 60 views
1

我需要根據每個人的地址獲取第三個移動日期。狀態改變或地址改變都會使DT發生改變。例如,對於PERSON_ID:1,第三個移動日期應該是07/16/2016。謝謝! 的數據如下:獲取第三個移動日期

PERSON_ID  STATUS  DT  ADDRESS 
1    12  5/6/2016  3 
1     6  5/8/2016  3 
1     7  6/5/2016  3 
1     1  6/13/2016  3 
1     12 6/20/2016  1 
1     17 7/8/2016  1 
1     1 7/11/2016  1 
1     12 7/16/2016  2 
1     3 12/6/2016  2 
2     5 3/11/2016  5 
2     1 5/15/2016  4 
2     6 7/18/2016  6 
2     12 7/21/2016  6 

回答

2

使用row_number()group bymin(dt)address

注:如果一個人在同一地址之間移動這將無法正常工作。

select 
    Person_id 
    , dt = convert(char(10),dt,120) 
    , Address 
from (
    select 
     person_id 
    , dt = min(dt) 
    , address 
    , rn = row_number() over (partition by person_id order by min(dt)) 
    from t 
    group by person_id, address 
) s 
where rn = 3 

rextester演示:http://rextester.com/VLTUU16478

回報:

+-----------+------------+---------+ 
| Person_id |  dt  | Address | 
+-----------+------------+---------+ 
|   1 | 2016-07-16 |  2 | 
|   2 | 2016-07-18 |  6 | 
+-----------+------------+---------+ 

要一個人在同一地址之間移動正確地解決這個問題,你必須解決的差距和島嶼問題。

添加一個額外的子查詢上述解決方案,因此我們可以通過島嶼識別和組:

select 
    Person_id 
    , dt = convert(char(10),dt,120) 
    , Address 
from (
    select 
     person_id 
    , dt = min(dt) 
    , address 
    , rn = row_number() over (partition by person_id order by min(dt)) 
    from (
    select 
     person_id 
     , address 
     , dt 
     , island = row_number() over (partition by person_id order by dt) 
       - row_number() over (partition by person_id, address order by dt) 
    from t 
    ) s 
    group by person_id, address, island 
) s 
where rn = 3 

rextester演示:http://rextester.com/PPIH49666

回報:

+-----------+------------+---------+ 
| Person_id |  dt  | Address | 
+-----------+------------+---------+ 
|   1 | 2016-07-16 |  3 | 
|   2 | 2016-07-18 |  5 | 
+-----------+------------+---------+ 
+0

。你有解決方案嗎?謝謝! – Ice

+0

@Ice更新第二個解決方案來解決差距和孤島問題。 – SqlZim

2

我不是當然,我明白你需要得到什麼,但我認爲你想要做的是這樣的:

如果此人移出的地址,後一個移動和移回原來的地址
SELECT * FROM 
(
SELECT person_id,adress,[status],DT, rank() over (partition by person_id order by adress,dt)-1 as movement 
FROM @t 
WHERE person_id=1 
) t 
WHERE t.movement=3 
0

問題並不完全清楚

select PERSON_ID, STATUS, DT, ADDRESS 
from (select PERSON_ID, STATUS, DT, ADDRESS 
      , row_number() over (partition by person order by dt) as rn 
     from (select PERSON_ID, STATUS, DT, ADDRESS 
        , row_number() over (partition by PERSON_ID, address order by dt) as rn 
       from table 
      ) tt 
      where tt.rn = 1 
    ) rr 
where rr.rn = 3 
相關問題