我如何计算行之间的间隙

时间:2017-02-06 19:45:05

标签: sql postgresql gaps-and-islands

现在我在我的应用ProcessXX中添加了一些并行性,我不确定数据是否可以按正确的顺序处理。所以我正在查询中返回下限和上限以传递给ProcessZZ

我的表格avl_pool包含avl_idhas_link以及其他一些字段和稳定的数据流,当新数据到达时,它们以has_link=null开始,当ProcessX结束时行has_link的链接值xxxx是一些数字。

现在在下一步我只需处理那些带链接的行,但我不能跳过行,因为顺序非常重要。

在这种情况下,我需要ProcessZZ(23561211, 23561219)

rn | avl_id    | has_link
1  | 23561211  | xxxx     --  start
2  | 23561212  | xxxx
3  | 23561213  | xxxx
4  | 23561214  | xxxx
5  | 23561215  | xxxx
6  | 23561216  | xxxx
7  | 23561217  | xxxx
8  | 23561218  | xxxx
9  | 23561219  | xxxx     -- end
10 | 23561220  | null
11 | 23561221  | xxxx
12 | 23561222  | xxxx
13 | 23561223  | xxxx

目前我有:

-- starting avl_id need to be send to ProcessZZ
SELECT MIN(avl_id) as min_avl_id
FROM avl_db.avl_pool
WHERE NOT has_link IS NULL

-- first avl_id still on hands of ProcessXX ( but can be null )
SELECT MIN(avl_id) as max_avl_id -- here need add a LAG
FROM avl_db.avl_pool
WHERE has_link IS NULL
  AND avl_id > (SELECT MIN(avl_id) 
                FROM avl_db.avl_pool
                WHERE NOT has_link IS NULL)

-- In case everyone has_link already the upper limit is the last one on the table.
SELECT MAX(avl_id) as max_avl_id
FROM avl_db.avl_pool

我可以在多个CTE中使用并返回两个结果,但我认为这可以像某个岛一样处理,但不确定如何。

所以查询看起来应该是

SELECT min_avl_id, min_avl_id
FROM cte 


min_avl_id  | min_avl_id
23561211    |  23561219

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要为每个块分配一个序号。此数字由NULL中的has_link值划分。

如果这是问题,那么累积总和可以解决问题:

select p.*,
       sum(case when has_link is null then 1 else 0 end) over (order by rn) as grp
from avl_db.avl_pool p;

这实际上包括输出中的NULL值。最简单的方法可能就是子查询:

select p.*
from (select p.*,
             sum(case when has_link is null then 1 else 0 end) over (order by rn) as grp
      from avl_db.avl_pool p
     ) p
where has_link is not null;