2017-09-27 56 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

確實!該功能剛剛在上週的雪花中可用:) –

相關問題