获取第三个搬家日期

Getting the third moving date

我需要根据每个人的地址获取第三个搬家日期。无论是状态改变还是地址改变都会使设备标识符发生变化。例如,对于 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

使用 row_number()group by 作为 min(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

returns:

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

returns:

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

我不确定我是否理解你需要得到什么,但我认为你想要做的是这样的:

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

问题不完全清楚

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