在 presto 中过滤 json 字段以计算整数的出现次数

Filtering a json field in presto to count occurences of integers

我在 table 中有一个 json 格式的字段,如下所示:

我想创建一个查询来计算数字 0 to 10 在键 employee_nps -> value 中出现的次数 如果我尝试使用此查询来计算数字 8 出现的次数:

SELECT
    count(CAST(filter(CAST(json_extract(answers, '$.employee_nps') AS ARRAY(MAP(VARCHAR, JSON))), x -> json_format(x['value'])='8') AS JSON))
FROM
    table

我收到以下错误:

error querying the database: INVALID_CAST_ARGUMENT: Cannot cast to array(map(varchar, json)). Expected a json array, but got { {"value":["10"]} 

注意:有时 value 可以为空,在极少数情况下 value 可以有字符串而不是整数,所以我想先检查值是否为整数。 我的预期结果是:

0 - count 10
1 - count 120
...
10 - count 100

employee_nps 属性 值(即 {"value": ["10"]})不是 ARRAY(MAP(VARCHAR, JSON))) 而只是 MAP(VARCHAR, JSON)),因此您需要对其进行转换。

但是如果您只对 value 感兴趣,您可以使用 '$.employee_nps.value' 路径准确提取它。然后你可以将值转换为 array(integer) (注意它将处理数字字符串的转换)并处理:

-- sample data
WITH dataset (answers) AS (
    VALUES (json '{"employee_nps": {"value": ["8"]}}'),
        (json '{"employee_nps": {"value": ["10", "11", "1"]}}')
)

--query
select cardinality( --count number of elements in array
        filter(
            cast(json_extract(answers, '$.employee_nps.value') as array(integer)),
            i->i between 0 and 10 -- filter out elements not between 0 and 10
        )
    ) result
from dataset

输出:

result
1
2

如果 value 的 json 值不是有效的数字数组,您可以根据所需的逻辑使用 try_cast (or try 来处理这种情况。

UPD

要计算数字,您可以使用 unnest 来展平数组:

--query
select num, count(num) num_count
from dataset
cross join unnest (cast(json_extract(answers, '$.employee_nps.value') as array(integer))) t(num)
where num between 0 and 10
group by num
order by num

输出:

num num_count
1 1
8 1
10 1