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