我有这样的表格行。
acc start_dat end_dat n_type
aa 1/1/2017 2/2/2017 er
aa 2/2/2017 4/2/2017 er
aa 4/2/2017 1/3/2017 ok
aa 1/3/2017 12/3/2017 ok
aa 12/3/2017 15/4/2017 er
aa 15/4/2017 3/5/2017 er
aa 3/5/2017 5/5/2017 er
aa 5/5/2017 null ok
bb 12/2/2017 4/3/2017 er
bb 4/3/2017 20/3/2017 er
bb 20/3/2017 13/4/2017 er
bb 13/4/2017 4/5/2017 ok
bb 4/5/2017 7/6/2017 er
bb 7/6/2017 3/7/2017 er
bb 3/7/2017 null ok
我想将更改前的最后一个状态分组为ok,end_Dat = null表示开始结束的计算日期
acc start_dat end_dat duration_day
aa 12/3/2017 5/5/2017 52
bb 4/5/2017 3/7/2017 60
你有什么想法解决它吗?
答案 0 :(得分:0)
您可以在每条记录之后计算“ok”记录的数量,然后将其用于聚合:
select acc, min(start_dat), max(end_dat),
(max(end_dat) - min(start_dat)) as diff
from (select t.*,
sum(case when n_type = 'ok' then 1 else 0 end) over (partition by acc order by start_dat desc) as numoks_after
from t
) t
where numoks_after = 1 and n_type <> 'ok'
group by acc;
答案 1 :(得分:0)
你的数学似乎不正确,从2017年12月3日到2017年5月5日的日数是54,而不是52.这是一个错字吗?
您需要使用相同的n_type
对连续的行进行分组。 &#34;连续&#34;按start_dat
排序,并为每个acc
分别完成分组。这是Tabibitosan方法的直接应用,用于在这样的&#34;间隙和岛屿中创建群组标识符。问题。 &#34; Tabibitosan方法&#34;是在下面的解决方案的最里面的子查询中使用两个row_number()
函数的差异,使用不同的partition by
子句。
除此之外,查询是标准的。按acc, n_type, grp
分组(其中grp
是在最里面的子查询中创建的新分组标志),计算每个组的最小开始日期和最大结束日期,并选择具有最高{{1}的组忽略grp
。
n_type = 'ok'