如何通过数组列内容筛选ClickHouse表?

13

我有一个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 '返回非零,则返回1。否则,返回0"。但是当我运行以下查询时,我得到三个零,而我应该得到一个零和两个一:

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

最终我想执行此选择,然后将其与表内容连接以仅返回具有exists = 1的行,但我需要先完成这一步骤。我使用arrayExists有误吗?更令我困惑的是,当我将比较值更改为2时,我会得到所有的1。这种过滤是否可以使用数组函数实现?

谢谢

2个回答

13

您可以在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

谢谢Mikhail,这个完美地解决了我的问题。我之前添加了arrayEnumerate,我想这可能是问题所在。我还想知道是否可以查询数组中的索引?比如说,如果我想检查distance[1] > 7,这样做是否会滥用数组功能,应该使用列来代替? - MoshMcCabe
2
是的,您可以检查数组中特定的元素SELECT * FROM ArrayTest WHERE distance[1] > 5 - Mikhail
谢谢Mikhail。现在对我来说一切都按预期工作。 - MoshMcCabe

1
我认为你得到三个零的原因是arrayEnumerate枚举数组索引而不是数组值,并且由于没有一行超过7个元素arrayEnumerates,所以所有行的结果都为0。为了使其工作,
SELECT arrayExists(
    val -> distance[val] > 7,
    arrayEnumerate(distance))
FROM ArrayTest;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接