在 Trino SQL 中使用 JSON_EXTRACT_SCALAR

问题描述 投票:0回答:1
面板 警报 日期
X [{"name":"x1","user_text":"","user_text_overflow":""},{"name":"y1","user_text":"","user_text_overflow":""}, {"name":"z1","user_text":"","user_text_overflow":""}] 2024-12-10
X [{"name":"x2","user_text":"","user_text_overflow":""},{"name":"x1","user_text":"","user_text_overflow":""}, {"name":"z2","user_text":"","user_text_overflow":""}] 2024-12-10
X [{"name":"x1","user_text":"","user_text_overflow":""},{"name":"x2","user_text":"","user_text_overflow":""}, {“名称”:“x3”,“user_text”:“”,“user_text_overflow”:“”}] 2024-12-11

鉴于上表,我尝试在设置为“x1”时提取“名称”值。我尝试过使用 json_extract_scalar 但我不断得到 NULL 值。我还想获得给定日期“name”为“x1”的次数总和

上面示例的预期结果应该是:

面板 名称 = x1 日期
X 2 2024-12-10
X 1 2024-12-11
sql trino json-extract
1个回答
0
投票

可能有一些用 Trino 来做到这一点的好方法,但我的想法喜欢用经典的宽表来思考,所以下面的答案(参见 https://hafizbadrie.medium.com/prestodb-convert-json-array-of- objects-into-rows-d9c916724dfc 有关正在发生的事情的更多描述)应该适合您...

-- create 3 rows of the test data 
WITH fake_table AS (
select 'X' AS panel, 
       '[{"name":"x1","user_text":"","user_text_overflow":""},{"name":"y1","user_text":"","user_text_overflow":""},{"name":"z1","user_text":"","user_text_overflow":""}]' AS alert,
       '2024-12-10' AS the_date
UNION
select 'X' AS panel, 
       '[{"name":"x2","user_text":"","user_text_overflow":""},{"name":"x1","user_text":"","user_text_overflow":""},{"name":"z2","user_text":"","user_text_overflow":""}]' AS alert,
       '2024-12-10' AS the_date
UNION
select 'X' AS panel, 
       '[{"name":"x1","user_text":"","user_text_overflow":""},{"name":"x2","user_text":"","user_text_overflow":""},{"name":"x3","user_text":"","user_text_overflow":""}]' AS alert,
       '2024-12-11' AS the_date
),

-- unwind it all to a deep and wide table representation
flattened_out_alerts AS (
select panel, the_date, 
       alert['name'] AS alert_name,
       alert['user_text'] AS alert_user_text,
       alert['user_text_overflow'] AS alert_user_text_overflow
  from (
        select panel, the_date,
               cast(json_extract(alert, '$') AS ARRAY<MAP<VARCHAR,VARCHAR>>) AS alerts
  from fake_table
  )
cross join UNNEST(alerts) AS alerts(alert)
)

-- run a normal group_by query
select the_date, alert_name, count(alert_name) AS the_count
  from flattened_out_alerts
 where alert_name = 'x1'
 group by the_date, alert_name;

它返回以下内容。

日期 警报名称 the_count
2024-12-11 x1 1
2024-12-10 x1 2
© www.soinside.com 2019 - 2024. All rights reserved.