Isa*_*c N 5 sql postgresql jsonpath set-returning-functions jsonb
在示例表中:
CREATE TABLE example (
id SERIAL PRIMARY KEY,
data JSON NOT NULL );
INSERT INTO example (id, data) VALUES
(1, '[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]')
, (2, '[{"key": "1", "value": "val1"}]')
, (3, '[{"key": "1", "value": "val1"}, {"key": "2", "value": "val2"}]');
Run Code Online (Sandbox Code Playgroud)
我想查询数据列中 key = 2 的值字段。我当前使用的查询是这样的:
SELECT id,
jsonb_path_query(
TO_JSONB(data),
'$[*] ? (@.key == "2").value'::JSONPATH
)::VARCHAR AS values
FROM example
Run Code Online (Sandbox Code Playgroud)
我期望结果是:
| ID | 价值观 |
|---|---|
| 1 | “值2” |
| 2 | 无效的 |
| 3 | “值2” |
但实际结果是:
| ID | 价值观 |
|---|---|
| 1 | “值2” |
| 3 | “值2” |
省略 null 输出是否有原因jsonb_path_query()?
我如何让它按照我期望的方式运行?
标量函数处理一个值,并且可以使该值无效,但是返回集合的函数 会生成值,因此它最终可能根本不生成值。正如已经建议的,您可以使用标量函数
\nSELECT id, jsonb_path_query_first(data::jsonb, \'$[*]?(@.key=="2").value\')\nFROM example;\nRun Code Online (Sandbox Code Playgroud)\n或者,您可以通过将 SRF(集合返回函数)jsonb_path_query()\xe2\x86\x92 setof jsonb包装在标量子查询中或替换其隐式内部联接来保留它。两者都会用 null 来指示缺少生成的值,但后者仍然可以生成并返回多个:demo
SELECT id,(SELECT jsonb_path_query(data::jsonb,\'$[*]?(@.key=="2").value\')LIMIT 1)\nFROM example;\n\nSELECT id, values\nFROM example LEFT JOIN jsonb_path_query(data::jsonb, \'$[*]?(@.key=="2").value\') \n AS srf(values) \n ON true;\nRun Code Online (Sandbox Code Playgroud)\n第 2 行没有在该函数中生成任何行,这就是您没有看到它的原因 - 没有行可以进入null。选择部分不是SRF 的正常位置- 当应用到此处时,它结束向上推向下至from节要inner joined带。有了inner join空集,就是空集。这与隐式连接行为相结合,就是为什么您可以阅读:
SELECT srf();作为实际的SELECT b.x FROM srf() AS b(x);
SELECT a.id, srf() FROM a;意义SELECT a.id, b.x FROM a, srf() AS b(x);
SELECT a.id, b.x FROM a, srf(a.v) AS b(x);实际上的意思是SELECT a.id, srf(a.v) FROM a;:
SELECT a.id, b.x FROM a INNER JOIN srf(a.v) AS b(x) ON true;
这INNER JOIN抛出了你id没有 result-genening 的 s data。LEFT JOIN惯于。
另一个插图更明显generate_series()“给我这么多行”SRF:演示
create table table1(id smallserial, how_many_to_generate int);\ninsert into table1(how_many_to_generate) values (1),(0),(2),(0),(1);\n\n--no rows for the 2nd and 4th entry where `how_many_to_generate` is 0\n--on the other hand, the 3rd entry requested and received two rows\nselect id, how_many_to_generate, generate_series(1, how_many_to_generate)\nfrom table1;\n-- id | how_many_to_generate | generate_series\n------+----------------------+-----------------\n-- 1 | 1 | 1\n-- 3 | 2 | 1\n-- 3 | 2 | 2\n-- 5 | 1 | 1\nRun Code Online (Sandbox Code Playgroud)\n
小智 4
jsonb_path_query_first()如果您想要路径表达式的结果,您需要:
SELECT id,
jsonb_path_query_first(data, '$[*] ? (@.key == "2").value') AS values
FROM example
Run Code Online (Sandbox Code Playgroud)
请注意,这会返回一个jsonb值。如果您想要一个text值,请使用:
jsonb_path_query_first(data, '$[*] ? (@.key == "2").value') #>> '{}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1283 次 |
| 最近记录: |