我正在使用Oracle(12cR2)json,但找不到查询包含某些元素的数组的方法。这是测试代码:
CREATE TABLE json_array (
id NUMBER NOT NULL,
array CLOB,
CONSTRAINT json_array_pk PRIMARY KEY (id),
CONSTRAINT json_array_chk_1 CHECK (array IS JSON)
);
INSERT INTO json_array (id, array) VALUES (1, '{"a":[1, 3]}');
INSERT INTO json_array (id, array) VALUES (2, '{"a":[2, 4, 6]}');
INSERT INTO json_array (id, array) VALUES (3, '{"a":[1, 2, 5]}');
INSERT INTO json_array (id, array) VALUES (4, '{"a":[2, 5]}');
INSERT INTO json_array (id, array) VALUES (5, '{"a":[5]}');
INSERT INTO json_array (id, array) VALUES (6, '{"a":[5, 2]}');
COMMIT;
创建域索引:
CREATE SEARCH INDEX idx_json_array ON json_array (array) FOR JSON;
我想查找包含数组元素2和5的所有行,无论它们在数组中的顺序如何,即SQL应该返回id为3,4,6的行。
我尝试了很多选择:
SQL1:
select * from json_array j -- return any arrays containing 2
where json_exists(j.array, '$?(@.a[0] == 2)');
==>返回包含2的行:id = 2,3,4,6
SQL2:
select * from json_array j -- return arrays containing 2 at index 1
where json_exists(j.array, '$?(@.a[0] == 2 || @.a[0] == 5)');
==>返回包含2或5的行:id = 2,4,5,6
SQL3:
select * from json_array j -- return arrays containing 2 at index 1
where json_exists(j.array, '$?(@.a[0] == 2 && @.a[0] == 5)');
==>不返回行
SQL4:
select * from json_array j -- returns arrays containing 2 OR 5
where json_textcontains(j.array, '$.a', '[2,5]');
==>返回包含2或5的行:id = 2,3,4,5,6
SQL5:
select * from json_array j
where json_textcontains(j.array, '$.a', '{[2] & [5]}');
==>返回包含2个AND 5的行,其中2个在5之前
唯一返回我想要的SQL是: SQL6:
select * from json_array j
where json_textcontains(j.array, '$.a', '[2]') AND json_textcontains(j.array, '$.a', '[5]');
==>返回id = 3,4,6
但是当元素数量增加时,这个解决方案会非常麻烦。
问题:SQL6有更好的选择可以返回相同的结果吗?
用于测试12c R2的Oracle版本
提前致谢
詹姆斯
答案 0 :(得分:0)
这有帮助......
SQL> with MY_TABLE as
2 (
3 select 1 as ID, '{"a":[1, 3]}' as ARRAY
4 from DUAL
5 union all
6 select 2 as ID, '{"a":[2, 4, 6]}' as ARRAY
7 from DUAL
8 union all
9 select 3 as ID, '{"a":[1, 2, 5]}' as ARRAY
10 from DUAL
11 union all
12 select 4 as ID, '{"a":[2, 5]}' as ARRAY
13 from DUAL
14 union all
15 select 5 as ID, '{"a":[5]}' as ARRAY
16 from DUAL
17 union all
18 select 6 as ID, '{"a":[5, 2]}' as ARRAY
19 from DUAL
20 )
21 select ID
22 from MY_TABLE
23 where json_exists(ARRAY,'$?(@.a == 2 && @.a == 5)')
24 /
ID
----------
3
4
6
SQL>