跳到主要内容
跳到主要内容

参数化聚合函数

一些聚合函数不仅可以接受列作为参数(用于压缩),还可以接受一组参数 - 初始化的常量。语法是两个括号对,而不是一个。第一个是用于参数,第二个是用于参数。

histogram

计算自适应直方图。它不保证精确的结果。

该函数使用 A Streaming Parallel Decision Tree Algorithm。随着新数据进入函数,直方图的区间边界会进行调整。在一般情况下,区间的宽度是不相等的。

参数

values表达式,产生输入值。

参数列表

number_of_bins — 直方图中区间的上限数量。该函数会自动计算区间的数量。它尝试达到指定的区间数量,但如果失败,它会使用更少的区间。

返回值

  • 数组元组,格式如下:

    • lower — 区间的下界。
    • upper — 区间的上界。
    • height — 计算出的区间高度。

示例

你可以用 bar 函数来可视化直方图,例如:

在这种情况下,你应该记住你不知道直方图区间的边界。

sequenceMatch

检查序列是否包含匹配模式的事件链。

语法

备注

在同一秒内发生的事件可能会以未定义的顺序排列在序列中,从而影响结果。

参数

  • timestamp — 被认为包含时间数据的列。典型数据类型是 DateDateTime。你也可以使用任何支持的 UInt 数据类型。

  • cond1, cond2 — 描述事件链的条件。数据类型:UInt8。最多可以传递 32 个条件参数。函数只考虑在这些条件中描述的事件。如果序列中包含未在条件中描述的数据,函数将跳过它们。

参数列表

返回值

  • 如果匹配模式,则返回 1。
  • 如果未匹配模式,则返回 0。

类型:UInt8

模式语法

  • (?N) — 匹配位置为 N 的条件参数。条件在 [1, 32] 范围内编号。例如, (?1) 匹配传递给 cond1 参数的参数。

  • .* — 匹配任意数量的事件。你不需要条件参数来匹配模式的这个部分。

  • (?t operator value) — 设置应分隔两个事件的时间(单位为秒)。例如,模式 (?1)(?t>1800)(?2) 匹配在 1800 秒以上发生的事件。任意数量的任何事件可以在这些事件之间。你可以使用 >=><<=== 操作符。

示例

考虑 t 表中的数据:

执行查询:

该函数找到事件链,其中数字 2 跟随数字 1。它跳过了它们之间的数字 3,因为该数字未被描述为事件。如果我们希望在搜索给定事件链时考虑到这个数字,我们应该为其设置一个条件。

在这种情况下,该函数未能找到匹配模式的事件链,因为数字 3 的事件发生在 1 和 2 之间。如果在同样的情况下检查数字 4 的条件,序列将匹配该模式。

参见

sequenceCount

计数匹配模式的事件链的数量。该函数搜索不重叠的事件链。它在当前链匹配后开始搜索下一个链。

备注

在同一秒内发生的事件可能会以未定义的顺序排列在序列中,从而影响结果。

语法

参数

  • timestamp — 被认为包含时间数据的列。典型数据类型是 DateDateTime。你也可以使用任何支持的 UInt 数据类型。

  • cond1, cond2 — 描述事件链的条件。数据类型:UInt8。最多可以传递 32 个条件参数。函数只考虑在这些条件中描述的事件。如果序列中包含未在条件中描述的数据,函数将跳过它们。

参数列表

返回值

  • 匹配的非重叠事件链的数量。

类型:UInt64

示例

考虑 t 表中的数据:

计算数字 2 在数字 1 之后的次数,允许它们之间有任意其他数字:

sequenceMatchEvents

返回匹配模式的最长事件链的事件时间戳。

备注

在同一秒内发生的事件可能会以未定义的顺序排列在序列中,从而影响结果。

语法

参数

  • timestamp — 被认为包含时间数据的列。典型数据类型是 DateDateTime。你也可以使用任何支持的 UInt 数据类型。

  • cond1, cond2 — 描述事件链的条件。数据类型:UInt8。你可以传递最多 32 个条件参数。函数只考虑在这些条件中描述的事件。如果序列中包含未在条件中描述的数据,函数将跳过它们。

参数列表

返回值

  • 事件链中匹配条件参数 (?N) 的时间戳数组。数组中位置与模式中条件参数的位置匹配。

类型:数组。

示例

考虑 t 表中的数据:

返回最长链的事件时间戳

参见

windowFunnel

在滑动时间窗口中搜索事件链并计算来自该链的事件发生的最大数量。

该函数按以下算法工作:

  • 该函数搜索触发链中第一个条件的数据,并将事件计数器设置为 1。这是滑动窗口开始的时刻。

  • 如果链中的事件在窗口内依次发生,则计数器递增。如果事件的顺序被打乱,则计数器不递增。

  • 如果数据有多条事件链在不同的完成点,函数只输出最长链的大小。

语法

参数

  • timestamp — 包含时间戳的列的名称。支持的数据类型:DateDateTime 和其他无符号整数类型(注意,尽管时间戳支持 UInt64 类型,但它的值不能超过 Int64 的最大值,即 2^63 - 1)。
  • cond — 描述事件链的条件或数据。 UInt8

参数列表

  • window — 滑动窗口的长度,它是第一个条件和最后一个条件之间的时间间隔。window 的单位取决于 timestamp 本身并有所不同。通过表达式 timestamp of cond1 <= timestamp of cond2 <= ... <= timestamp of condN <= timestamp of cond1 + window 确定。
  • mode — 可选参数。可以设置一个或多个模式。
    • 'strict_deduplication' — 如果事件序列中相同的条件成立,则这样的重复事件会中断进一步处理。注意:如果多个条件对同一个事件成立,它可能会表现得不如预期。
    • 'strict_order' — 不允许其他事件的干预。例如,在 A->B->D->C 的情况下,它在 D 停止寻找 A->B->C,最大事件级别为 2。
    • 'strict_increase' — 仅将条件应用于时间戳严格递增的事件。
    • 'strict_once' — 即使事件满足条件多次,也只在链中计算每个事件一次。

返回值

在滑动时间窗口内,从链中连续触发的条件的最大数量。 选定的所有链都会被分析。

类型:Integer

示例

确定用户在网上商店中选择电话并购买两次所需的时间是否足够。

设置以下事件链:

  1. 用户登录到商店账户 (eventID = 1003)。
  2. 用户搜索电话 (eventID = 1007, product = 'phone')。
  3. 用户下单 (eventID = 1009)。
  4. 用户再次下单 (eventID = 1010)。

输入表:

找出在 2019 年 1 月至 2 月期间,用户 user_id 能通过链达到的程度。

查询:

结果:

retention

该函数以条件集作为参数,条件集最多包含 32 个 UInt8 类型的参数,指示事件是否满足特定条件。 任何条件都可以作为参数指定(如在 WHERE 中)。

除了第一个条件外,其他条件以成对的方式应用:第二个的结果将为 true 如果第一个和第二个都为 true,第三个的结果将为 true 如果第一个和第三个都为 true,等等。

语法

参数

  • cond — 返回 UInt8 结果(1 或 0)的表达式。

返回值

返回 1 或 0 的数组。

  • 1 — 事件满足条件。
  • 0 — 事件不满足条件。

类型:UInt8

示例

考虑一个示例,使用 retention 函数来确定站点流量。

1. 创建一个表来说明这个示例。

输入表:

查询:

结果:

2. 使用 retention 函数按唯一 ID uid 对用户进行分组。

查询:

结果:

3. 计算每天的站点访问总数。

查询:

结果:

其中:

  • r1 - 在 2020-01-01 时访问站点的独立访客数量(cond1 条件)。
  • r2 - 在 2020-01-01 和 2020-01-02 之间的特定时间段内访问站点的独立访客数量(cond1cond2 条件)。
  • r3 - 在 2020-01-01 和 2020-01-03 期间访问站点的独立访客数量(cond1cond3 条件)。

uniqUpTo(N)(x)

计算参数中不同值的数量,直到指定的限制 N。如果不同参数值的数量大于 N,则此函数返回 N + 1,否则它计算确切值。

建议与小的 N 一起使用,最多 10。N 的最大值为 100。

对于聚合函数的状态,此函数使用的内存量等于 1 + N * 一个值的字节数。 在处理字符串时,此函数存储一个非加密的 8 字节哈希;对字符串的计算是近似的。

例如,如果你有一个记录用户在你的网站上进行的每个搜索查询的表。表中的每一行代表一个单独的搜索查询,包含用户 ID、搜索查询和查询的时间戳。你可以使用 uniqUpTo 创建一个报告,仅显示至少有 5 个独特用户使用的关键词。

uniqUpTo(4)(UserID) 计算每个 SearchPhrase 的唯一 UserID 值的数量,但它只计算最多 4 个唯一值。如果某个 SearchPhrase 的唯一 UserID 值超过 4 个,函数返回 5(4 + 1)。HAVING 子句然后过滤出其唯一 UserID 值少于 5 的 SearchPhrase 值。这将提供至少有 5 个独特用户使用的搜索关键词的列表。

sumMapFiltered

此函数的行为与 sumMap 相同,只不过它还接受一个要过滤的键数组作为参数。这在处理键的高基数时特别有用。

语法

sumMapFiltered(keys_to_keep)(keys, values)

参数

返回值

  • 返回一个包含两个数组的元组:按顺序排列的键和对应键的求和值。

示例

查询:

结果:

sumMapFilteredWithOverflow

此函数的行为与 sumMap 相同,只不过它还接受一个要过滤的键数组作为参数。这在处理键的高基数时特别有用。它与 sumMapFiltered 函数的不同之处在于,它在求和时处理溢出 - 即返回与求和参数相同的数据类型。

语法

sumMapFilteredWithOverflow(keys_to_keep)(keys, values)

参数

返回值

  • 返回一个包含两个数组的元组:按顺序排列的键和对应键的求和值。

示例

在这个示例中,我们创建一个 sum_map 表,插入一些数据,然后分别使用 sumMapFilteredWithOverflowsumMapFiltered 以及 toTypeName 函数比较结果。由于 requests 在创建的表中的类型为 UInt8sumMapFiltered 为了避免溢出将求和值的类型提升到 UInt64,而 sumMapFilteredWithOverflow 保持类型为 UInt8,这不足以存储结果 - 即发生了溢出。

查询:

结果:

sequenceNextNode

返回与事件链匹配的下一个事件的值。

实验性功能,SET allow_experimental_funnel_functions = 1 以启用它。

语法

参数

  • direction — 用于导航方向。

    • forward — 向前移动。
    • backward — 向后移动。
  • base — 用于设置基点。

    • head — 将基点设置为第一个事件。
    • tail — 将基点设置为最后一个事件。
    • first_match — 将基点设置为第一个匹配的 event1
    • last_match — 将基点设置为最后一个匹配的 event1

参数说明

  • timestamp — 包含时间戳的列的名称。支持的数据类型:DateDateTime 及其他无符号整数类型。
  • event_column — 包含要返回的下一个事件值的列的名称。支持的数据类型:StringNullable(String)
  • base_condition — 基点必须满足的条件。
  • event1, event2, ... — 描述事件链的条件。 UInt8

返回值

  • event_column[next_index] — 如果模式匹配且下一个值存在。
  • NULL - 如果模式不匹配或下一个值不存在。

类型:Nullable(String)

示例

可以在事件为 A->B->C->D->E 时使用,并想知道跟随 B->C 的事件是 D。

查询语句查找 A->B 后的事件:

结果:

forwardhead 的行为

backwardtail 的行为

forwardfirst_match 的行为

backwardlast_match 的行为

base_condition 的行为