如何按数组列内容过滤clickhouse表?

2w3kk1z5  于 2021-07-15  发布在  ClickHouse
关注(0)|答案(2)|浏览(614)

我有一个clickhouse表,它有一个数组(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的行。我在这里找到了array operators文档,并尝试了arrayexists函数,但它并没有像我期望的那样工作。从文档中可以看出,此函数“如果'arr'中至少有一个元素'func'返回0以外的值,则返回1。否则,返回0”。但当我运行下面的查询时,返回了三个0,其中我应该得到一个0和两个1:

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

最后,我想执行这个select,然后将它与表内容连接起来,只返回exists=1的行,但我需要在这之前完成第一步。我是不是用错了arrayexists?我发现更让人困惑的是,当我把比较值改为2时,我得到了所有的1。这种滤波能用数组函数实现吗?
谢谢

0wi1tuuw

0wi1tuuw1#

可以在where子句中使用arrayexists。

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

另一种方法是使用数组联接,如果需要知道哪些值大于7:

SELECT d, distance, sessionSecond 
FROM ArrayTest
ARRAY JOIN distance as d
WHERE d > 7
kxkpmulp

kxkpmulp2#

我认为得到3个零的原因是arrayenumerate枚举数组索引而不是数组值,并且由于您的行中没有超过7个元素,因此arrayenumerate会为所有行生成0。为了让这一切顺利进行,

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

相关问题