在 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
我在 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 |