假设我期望以下 JSON:
{
"key": "value"
}
我想创建一个物化视图,将
key
显示为一列。数据来自Kinesis Streaming Data,因此它必须支持增量刷新,因为它每分钟可能包含数百万条新记录。我尝试了几种方法,其中之一:
CREATE MATERIALIZED VIEW kd.streams
AUTO REFRESH NO
AS
SELECT approximate_arrival_timestamp AS apx_arv_at,
JSON_PARSE(kinesis_data).key AS key_value
FROM kd_stream."kinesis-stream"
WHERE CAN_JSON_PARSE(kinesis_data);
结果是:
ERROR: syntax error at or near "."
LINE 5: JSON_PARSE(kinesis_data).key AS...
我尝试了
JSON_EXTRACT_PATH_TEXT
、投射到JSON
以及其他一些方法。
如果我只是将列创建为 json (
JSON_PARSE(kinesis_data)
),它就可以工作,但这意味着我需要在其上构建另一个 MV。仅供参考 kinesis_data
是 binary varying
,kinesis-stream
是运动流(不是表)。
根据您正在尝试的内容,我假设 kinesis_data 是字符串/文本。您看到的错误是因为查询解析器在运行时不知道“key”。您会看到这个超级值直到运行时才创建。所以当它看到“.”时它不知道该怎么办。
如果 kinesis_data 是 super 类型,则使用“.”当解析器知道这是 super 的(潜在)部分时,符号将起作用。如果您认为 Redshift 在这方面应该更聪明,我怀疑您需要提交案例。
现在获得您想要的内容已经很简单了,但首先我需要了解“转换为 JSON”的含义,因为 JSON 不是 Redshift 数据类型。我猜你想要一个只有字符串的 super,但这还不清楚。
我将重点关注 MV 定义中的选择查询,因为这是问题所在。
修复 #1 - 添加 with 子句。
如果我们从以下定义的测试表开始:
create table test as select '{
"key": "value"
}' as col;
我们可以通过以下方式提取值:
with super as (
SELECT JSON_PARSE(col) AS key_value
FROM test
WHERE CAN_JSON_PARSE(col))
select key_value, key_value.key
from super;
修复 #2 - 使用 JSON_EXTRACT_PATH_TEXT
使用与 #1 相同的测试表,我们可以:
SELECT col, json_parse('"'||JSON_EXTRACT_PATH_TEXT(col,'key')||'"') AS key_value
FROM test
WHERE CAN_JSON_PARSE(col);
如果您想要一个字符串而不是 super,则不需要 json_parse 和这里的所有引用。
最后,作为健全性检查,解析器如何处理“.”。当表数据为超级时的表示法:
create table test2 as select json_parse('{
"key": "value"
}') as col;
select col.key
from test2;
我希望这可以帮助您获得所需的东西。
==============================更新==================== ========
根据评论,这里有一些修改后的代码。
创建测试表作为 varbyte 数据:
create table test as select '{
"key": "value"
}'::varbyte as col;
用代码1制作物化视图:
create materialized view public.ttt
auto refresh no
as
with super as (
SELECT JSON_PARSE(col) AS key_value
FROM test
WHERE CAN_JSON_PARSE(col))
select key_value, key_value.key
from super;
这可以工作,但由于从超类型(不可追踪)中提取“密钥”而无法增量更新,并且可能使用也增加了一些间接性的 cte。
从代码2制作物化视图:
create materialized view public.ttt
auto refresh no
as
SELECT col, json_parse('"'||JSON_EXTRACT_PATH_TEXT(col,'key')||'"') AS key_value
FROM test
WHERE CAN_JSON_PARSE(col);
这没有增量更新限制。