如何将可重复的分区作为一个又一个分区的新分区?

Posted

技术标签:

【中文标题】如何将可重复的分区作为一个又一个分区的新分区?【英文标题】:How to get repeatable partition as new one after another partition? 【发布时间】:2019-03-24 16:27:26 【问题描述】:

OVER 子句中的“Partition by”将所有值分组为唯一值,就像“Distinct”或“Group by”一样。

这就是它在我的 row_number() 查询中的工作方式:

    id st t  row_number
    -------------------
    1  1  1  1
    1  1  2  2
    1  1  3  3
    2  1  3  1
    1  2  4  1
    1  1  10 4

这就是我想要的:

    id st t  uniq_row_number
    ------------------
    1  1  1  1
    1  1  2  2
    1  1  3  3
    2  1  3  1
    1  2  4  1
    1  1  10 1

无论之前是否有新字符串,每次更改分区后都会将其读取为新分区。 如果分区重复,则 uniq_row_number 得到 +1。如果新分区带有新字符串:boom,则得到 uniq_row_number 1。

我的 SQL 查询:

    SELECT id, st, t,
    row_number() OVER (PARTITION BY id, st ORDER BY id, st) cat_num,
    min(t) over (PARTITION BY id, st) min_t,
    max(t) over (PARTITION BY id, st) max_t
    FROM tabl ORDER BY t;

SQL 代码在这里:http://sqlfiddle.com/#!18/d4290/2

【问题讨论】:

"if new string already was before" - 要说一行是 before 另一行,您需要一列(或一组列)来确定顺序。那么这些列是什么?为什么 (1, 2, 4) (1, 1, 10) 之前? @paul-spiegel,在这个例子中我编码了row_number() OVER (PARTITION BY id, st) row_number,两列。所以在最后一行我在'1 1 10'附近得到'4',因为'1 1'已经在第一行,第二行和第三行。我想要'1 1 10'附近的'1'而不是'4',因为在第三行和第六行之间还有另一个分区。 【参考方案1】:

这被称为“差距和岛屿”问题。您需要为每个具有相似值的“岛”定义一个组。然后你可以使用row_number()

行号的不同是定义孤岛的便捷方式:

select t.*,
       row_number() over (partition by id, seqnum_t - seqnum_it
                          order by t
                         ) as uniq_row_number
from (select t.*,
             row_number() over (order by t) as seqnum_t,
             row_number() over (partition by id order by t) as seqnum_it,
      from t
     ) t;

了解其工作原理的最佳方法是查看子查询的结果。您应该能够看到行号的差异如何定义您关心的组。

【讨论】:

以上是关于如何将可重复的分区作为一个又一个分区的新分区?的主要内容,如果未能解决你的问题,请参考以下文章

删除每个分区的重复项

如何通过重复计数逻辑处理 row_number 分区中的空列?

磁盘分区开机自动挂载

BigQuery 重复数据删除和分区表

如何通过重复计数逻辑处理row_number分区中的空列?

Linux主分区,扩展分区,逻辑分区的联系和区别