在 ClickHouse 中使用 Array(Tuple(LowCardinality(String), Int32))
Posted
技术标签:
【中文标题】在 ClickHouse 中使用 Array(Tuple(LowCardinality(String), Int32))【英文标题】:Using Array(Tuple(LowCardinality(String), Int32)) in ClickHouse 【发布时间】:2020-03-20 05:05:00 【问题描述】:我有一张桌子
CREATE TABLE table (
id Int32,
values Array(Tuple(LowCardinality(String), Int32)),
date Date
) ENGINE MergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (id, date)
但是在执行请求的时候
SELECT count(*)
FROM table
WHERE (arrayExists(x -> ((x.1) = toLowCardinality('pattern')), values) = 1)
我收到一个错误
Code: 49. DB::Exception: Received from clickhouse:9000. DB::Exception: Cannot capture column 3 because it has incompatible type: got String, but LowCardinality(String) is expected..
如果我替换列“值” 值数组(元组(字符串,Int32)) 然后请求被正确执行。
使用 Array(Tuple(LowCardinality(String), Int32)) 时会出现什么问题?
【问题讨论】:
看来是bug:github.com/ClickHouse/ClickHouse/issues/7815 【参考方案1】:直到它被修复(见bug 7815),可以使用这个解决方法:
SELECT uniqExact((id, date)) AS count
FROM table
ARRAY JOIN values
WHERE values.1 = 'pattern'
对于有多个数组的情况,可以这样使用:
SELECT uniqExact((id, date)) AS count
FROM
(
SELECT
id,
date,
arrayJoin(values) AS v,
arrayJoin(values2) AS v2
FROM table
WHERE v.1 = 'pattern' AND v2.1 = 'pattern2'
)
【讨论】:
谢谢,但问题是我不能使用 ARRAY JOIN 两次来限制两个这样的字段【参考方案2】:values Array(Tuple(LowCardinality(String), Int32)),
不要使用Tuple
。它只会带来缺点。
它仍然是磁盘上的 *2 个文件。
它会减慢两倍,然后您只提取一个元组元素
https://gist.github.com/den-crane/f20a2dce94a2926a1e7cfec7cdd12f6d
valuesS Array(LowCardinality(String)),
valuesI Array(Int32)
【讨论】:
我使用 Tuple 来存储 Key-Value 值,并通过键值过滤,我使用值。存储在两个独立的数组中不适合我。 @ask125342 所有高阶函数都接受多个数组 select arrayFilter((v, k) -> k = 'a', values, keys) from (select ['a','a',' b','a'] 键,[1,2,3,4] 值)以上是关于在 ClickHouse 中使用 Array(Tuple(LowCardinality(String), Int32))的主要内容,如果未能解决你的问题,请参考以下文章
大数据ClickHouse进阶:ClickHouse的Array Join子句