从组中选择特定事件 SQL
selecting specific occurrences from a group SQL
数据集看起来像
id statusid statusdate
100 22 04/12/2016
100 22 04/14/2016
100 25 04/16/2016
100 25 04/17/2016
100 25 04/19/2016
100 22 04/22/2016
100 22 05/14/2016
100 27 05/19/2016
100 27 06/14/2016
100 25 06/18/2016
100 22 07/14/2016
100 22 07/18/2016
任务是 select 第一次记录每个状态。记录每个状态的唯一次数。
示例:
对于状态 22
- 首次状态日期:2016 年 4 月 12 日
- 最后一次状态第一个日期:07/14/2016
- 进入该状态的唯一次数:3
这比看起来要复杂。我假设您想要给定状态的唯一连续时间。
使用不同的行号方法将连续的行分类到组中。然后获取这些组中的行号。最后聚合得到第一个和最后一个组中的第一天和不同组的数量。
select statusid
,max(case when rn_grp_asc=1 then statusdate end) as last_time_first_status
,max(case when rn_grp_desc=1 then statusdate end) as last_time_first_status
,count(distinct grp) as unique_times_in_status
from (select t.*
,row_number() over(partition by statusid order by grp,statusdate) as rn_grp_asc
,row_number() over(partition by statusid order by grp desc,statusdate) as rn_grp_desc
from (select t.*,row_number() over(order by statusdate)
-row_number() over(partition by statusid order by statusdate) as grp
from tbl t
) t
) t
group by statusid
select ID,
statusid,
Status,
max(case when rn_grp_asc=1 then statusdate end) as frst_time_first_status,
max(case when rn_grp_desc=1 then statusdate end) as last_time_first_status,
count(distinct grp) as unique_times_in_status
from ( select t.*,
row_number() over(partition by id,statusid order by grp,statusdate) as rn_grp_asc,
row_number() over(partition by id,statusid order by grp desc,statusdate) as rn_grp_desc
from ( Select ID,
StatusID,
Status,
StatusDate,
row_number() over(partition by id order by Systemdate)-row_number() over(partition by id,statusid order by Systemdate) as grp
from t
where ID=100
) t
) t
group by id,statusid,Status
上面的查询returns正确的结果,但是下面的查询没有。
select ID,
statusid,
Status,
max(case when rn_grp_asc=1 then statusdate end) as frst_time_first_status,
max(case when rn_grp_desc=1 then statusdate end) as last_time_first_status,
count(distinct grp) as unique_times_in_status
from ( select t.*,
row_number() over(partition by id,statusid order by grp,statusdate) as rn_grp_asc,
row_number() over(partition by id,statusid order by grp desc,statusdate) as rn_grp_desc
from ( Select ID,
StatusID,
Status,
StatusDate,
row_number() over(partition by id order by Systemdate)-row_number() over(partition by id,statusid order by Systemdate) as grp
from t
) t
) t
where ID=100
group by id,statusid,Status
数据集看起来像
id statusid statusdate
100 22 04/12/2016
100 22 04/14/2016
100 25 04/16/2016
100 25 04/17/2016
100 25 04/19/2016
100 22 04/22/2016
100 22 05/14/2016
100 27 05/19/2016
100 27 06/14/2016
100 25 06/18/2016
100 22 07/14/2016
100 22 07/18/2016
任务是 select 第一次记录每个状态。记录每个状态的唯一次数。
示例: 对于状态 22
- 首次状态日期:2016 年 4 月 12 日
- 最后一次状态第一个日期:07/14/2016
- 进入该状态的唯一次数:3
这比看起来要复杂。我假设您想要给定状态的唯一连续时间。 使用不同的行号方法将连续的行分类到组中。然后获取这些组中的行号。最后聚合得到第一个和最后一个组中的第一天和不同组的数量。
select statusid
,max(case when rn_grp_asc=1 then statusdate end) as last_time_first_status
,max(case when rn_grp_desc=1 then statusdate end) as last_time_first_status
,count(distinct grp) as unique_times_in_status
from (select t.*
,row_number() over(partition by statusid order by grp,statusdate) as rn_grp_asc
,row_number() over(partition by statusid order by grp desc,statusdate) as rn_grp_desc
from (select t.*,row_number() over(order by statusdate)
-row_number() over(partition by statusid order by statusdate) as grp
from tbl t
) t
) t
group by statusid
select ID,
statusid,
Status,
max(case when rn_grp_asc=1 then statusdate end) as frst_time_first_status,
max(case when rn_grp_desc=1 then statusdate end) as last_time_first_status,
count(distinct grp) as unique_times_in_status
from ( select t.*,
row_number() over(partition by id,statusid order by grp,statusdate) as rn_grp_asc,
row_number() over(partition by id,statusid order by grp desc,statusdate) as rn_grp_desc
from ( Select ID,
StatusID,
Status,
StatusDate,
row_number() over(partition by id order by Systemdate)-row_number() over(partition by id,statusid order by Systemdate) as grp
from t
where ID=100
) t
) t
group by id,statusid,Status
上面的查询returns正确的结果,但是下面的查询没有。
select ID,
statusid,
Status,
max(case when rn_grp_asc=1 then statusdate end) as frst_time_first_status,
max(case when rn_grp_desc=1 then statusdate end) as last_time_first_status,
count(distinct grp) as unique_times_in_status
from ( select t.*,
row_number() over(partition by id,statusid order by grp,statusdate) as rn_grp_asc,
row_number() over(partition by id,statusid order by grp desc,statusdate) as rn_grp_desc
from ( Select ID,
StatusID,
Status,
StatusDate,
row_number() over(partition by id order by Systemdate)-row_number() over(partition by id,statusid order by Systemdate) as grp
from t
) t
) t
where ID=100
group by id,statusid,Status