10

我有一个 clickhouse 表,它有一个 Array(UInt16) 列。我希望能够从该表中过滤结果,以仅获取数组列中的值高于阈值的行。我一直在尝试使用一些数组函数(arrayFilter 和 arrayExists)来实现这一点,但我对 SQL/Clickhouse 查询语法不够熟悉,无法使其正常工作。

我使用以下方法创建了表:

CREATE TABLE IF NOT EXISTS ArrayTest (
    date Date,
    sessionSecond UInt16,
    distance Array(UInt16)
) Engine = MergeTree(date, (date, sessionSecond), 8192);

其中距离值将是在日期之后的特定秒数 (sessionSecond) 处与特定点的距离。我添加了一些示例值,因此表格如下所示:

带有样本值的表

现在我想获取所有包含距离大于 7 的行。我在这里找到了数组运算符文档并尝试了 arrayExists 函数,但它没有按我的预期工作。从文档中,它说这个函数“如果'arr'中至少有一个元素'func'返回0以外的东西,则返回1。否则,它返回0”。但是当我运行下面的查询时,我得到了三个零,我应该得到一个 0 和两个 1:

SELECT arrayExists(
    val -> val > 7,
    arrayEnumerate(distance))
FROM ArrayTest;

最终我想执行这个选择,然后将它与表内容连接起来,只返回存在存在 = 1 的行,但在此之前我需要这第一步才能工作。我使用 arrayExists 错误吗?我发现更令人困惑的是,当我将比较值更改为 2 时,我得到的都是 1。使用数组函数可以实现这种过滤吗?

谢谢

4

2 回答 2

10

您可以在 WHERE 子句中使用 arrayExists。

SELECT * 
FROM ArrayTest
WHERE arrayExists(x -> x > 7, distance) = 1;

另一种方法是使用 ARRAY JOIN,如果您需要知道哪些值大于 7:

SELECT d, distance, sessionSecond 
FROM ArrayTest
ARRAY JOIN distance as d
WHERE d > 7
于 2017-12-01T15:24:52.257 回答
1

我认为你得到 3 个零的原因是 arrayEnumerate 枚举数组索引而不是数组值,并且因为你的行没有超过 7 个元素arrayEnumerates导致所有行都为 0。为了使这项工作,

SELECT arrayExists(
    val -> distance[val] > 7,
    arrayEnumerate(distance))
FROM ArrayTest;
于 2020-09-04T03:47:51.887 回答