2017-09-27 58 views
1

我想存储数百万个时间序列,其中每个时间序列的每个时间点都标有任意一组标签。 看来我应该在雪花使用JSON阵列标签:如何在雪花中使用JSON时使用数组中的标签进行过滤

CREATE TABLE timeseries (obj_id INT, ts DATE, tags VARIANT, val INT) 
INSERT INTO timeseries (obj_id, ts, tags, val) VALUES (442243, '2017-01-01', parse_json('["red", "small", "cheap"]'), 1) 
INSERT INTO timeseries (obj_id, ts, tags, val) VALUES (673124, '2017-01-01', parse_json('["red", "small", "expensive"]'), 2) 
INSERT INTO timeseries (obj_id, ts, tags, val) VALUES (773235, '2017-01-01', parse_json('["black", "small", "cheap"]'), 3) 

现在我想看到标有“小”和“便宜”,例如所有的时间序列的平均

SELECT ts, AVG(val) 
FROM timeseries 
WHERE "small" IN tags AND "cheap" IN tags 
GROUP BY ts 

这将返回:

ts, avg(val) 
2017-01-01, 2 

什么是正确的语法雪花/模式/方法来实现呢? 请注意,我不想FLATTEN爆炸行,我只是想过滤掉所有不是'便宜'和'小'的行。

回答

1

而不是使用JSON,就可以直接使用E.g数组类型:

CREATE TABLE ts2 (obj_id INT, ts DATE, tags ARRAY, val INT); 
INSERT INTO ts2 (obj_id, ts, tags, val) select 442243, '2017-01-01', ARRAY_CONSTRUCT('red', 'small', 'cheap'), 1; 
INSERT INTO ts2 (obj_id, ts, tags, val) select 673124, '2017-02-01', ARRAY_CONSTRUCT('red', 'small', 'expensive'), 2; 
INSERT INTO ts2 (obj_id, ts, tags, val) select 773235, '2017-01-01', ARRAY_CONSTRUCT('black', 'small', 'cheap'), 3; 

值子句不能使用的功能,如ARRAY_CONSTRUCT,但INSERT-SELECT会工作。 (你也可以用JSON和VARIANT类型来做到这一点,但你需要用键名来标记值,并在插入中使用PARSE_JSON。)

然后要查询只包含两个标签的行选择,使用这样的查询:

select 
    obj_id, 
    tags 
from ts2 
where ARRAY_CONTAINS('small'::variant, tags) 
    and ARRAY_CONTAINS('cheap'::variant, tags) 
; 
+0

谢谢!我会试试看! –

+0

ARRAY_CONTAINS应该也适用于Andrey的加载数据的方式,顺便说一句。 –

+0

确实!该功能刚刚在上周的雪花中可用:) –

相关问题