【问题标题】:Group data series into variable width windows based on first event根据第一个事件将数据系列分组为可变宽度窗口
【发布时间】:2021-12-31 23:19:16
【问题描述】:

我的计算任务可以简化为以下问题:

我有一大组整数对(key、val),我想将它们分组到窗口中。第一个窗口从按 key 属性排序的第一对 p 开始,并跨越 p[i].key 属于 的所有对>[p[0].key; p[0].key + N),具有任意整数 N,对所有窗口都是正数。

下一个窗口从前一个窗口中未包含的由 key 排序的第一对开始,并再次跨越从其 key 到 key + N 的所有对,以此类推,适用于以下窗口。

最后一步是对每个窗口的第二个属性求和,并与窗口的第一个键一起显示。

例如,给定具有值的记录列表:

key val
1 3
2 7
5 1
6 4
7 1
10 3
13 5

并且 N=3,窗口将是:

  • {(1,3),(2,7)},
  • {(5,1),(6,4),(7,1)},
  • {(10,3)}
  • {(13,5)}

最终结果:

key sum_of_values
1 10
5 6
10 3
13 5

这很容易用标准编程语言编程,但我不知道如何用 SQL 解决这个问题。

【问题讨论】:

  • 标记您要使用的 rdbms(sql server、mysql、oracle 等)。另外,这组键1,2,3,4 会发生什么?他们会组成一组1,2,3,4 还是1,2,3 和4?
  • @SalmanA,它已被标记为 clickhouse,但当然欢迎使用通用解决方案。 N=3 时,1,2,3,4 应分组为 {1,2,3} 和 {4}。第一组从 1 开始,包含范围 [1; 4) 其中不包含 4,因此单独分组。
  • 所以问题应该说明:from key to key + (N-1)
  • 即使它可以用 CH 解决(而且我认为它可以用 Arrays 解决)它是没用的,它不是 MPP 任务,你不能在线程和分片之间共享计算,它可以在一个仅限单线程。
  • @DennyCrane,为了更容易理解,我稍微简化了问题。真正的用户包括许多用户,每个用户都有单独的 (key, val) 对。所以每个用户都可以单独处理。关于数组解决方案的任何提示?

标签: sql clickhouse


【解决方案1】:

注意:如果 clickhouse 不支持 RECURSIVE 关键字,只需从表达式中删除该关键字即可。

Clickhouse 似乎对WITH clause 使用了非标准语法。下面使用标准 SQL。根据需要进行调整。

对不起。 clickhouse 可能不支持这种方法。如果没有,我们需要找到另一种遍历数据的方法。

标准 SQL: 有几种方法。这是一种方法。首先分配行号以允许递归地遍历行。我们也可以使用LEAD。

根据当前key和最后一个group/key value以及它们是否在一定距离内(N = 3, in this case)为每一行分配一个组(键值)。

最后一步是只为每个组start_key 设置这些值SUM,并使用start_key 值作为每个组中的起始key。

WITH RECURSIVE nrows (xkey, val, n) AS (
        SELECT xkey, val, ROW_NUMBER() OVER (ORDER BY xkey) FROM test
     )
   , cte (xkey, val, n, start_key) AS (
        SELECT xkey, val, n, xkey FROM nrows WHERE n = 1
         UNION ALL
        SELECT t1.xkey, t1.val, t1.n
             , CASE WHEN t1.xkey <= t2.start_key + (3-1) THEN t2.start_key ELSE t1.xkey END
          FROM nrows AS t1
          JOIN cte   AS t2
            ON t2.n = t1.n-1
     )
SELECT start_key
     , SUM(val) AS sum_values
  FROM cte
 GROUP BY start_key
 ORDER BY start_key
;

结果:

+-----------+------------+
| start_key | sum_values |
+-----------+------------+
|         1 |         10 |
|         5 |          6 |
|        10 |          3 |
|        13 |          5 |
+-----------+------------+

【讨论】:

  • 我希望我可以将其标记为解决方案,但不幸的是 clickhouse 不支持递归 CTE。不过谢谢,我从你的回答中学到了一些新东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 2016-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多