[英]Search a JSON array in Oracle
I'm trying to use the new JSON features introduced in Oracle 12.1.0.2 我正在尝试使用Oracle 12.1.0.2中引入的新JSON功能
However I can't seem to find a way to look for a specific value in an array inside my JSON document. 但是我似乎找不到在JSON文档中查找数组中特定值的方法。
Consider the following table and data: 请考虑以下表格和数据:
create table orders
(
id integer not null primary key,
details clob not null check (details is json (strict))
);
insert into orders (id, details) values
(1, '{"products": [{ "product": 1, "quantity": 5}, {"product": 2, "quantity": 1}], "delivery_address": "My hometown"}');
insert into orders (id, details) values
(2, '{"products": [{ "product": 42, "quantity": 1}, {"product": 10, "quantity": 2}], "comment": "Your website is too slow"}');
insert into orders (id, details) values
(3, '{"products": [{ "product": 543, "quantity": 1}], "discount": "15"}');
insert into orders (id, details) values
(4, '{"products": [{ "product": 738, "quantity": 12}], "discount": "32"}');
Now I'm trying to write a SQL query that returns all orders, where product #2 was ordered. 现在我正在尝试编写一个返回所有订单的SQL查询,其中订购了产品#2。
I can't use json_exists
because it doesn't allow array expressions (and I wouldn't know how to specify the value anyway). 我不能使用json_exists
因为它不允许数组表达式(我不知道如何指定值)。
json_value
only returns a single value, so I can't "iterate" over the array values. json_value
只返回一个值,所以我不能“迭代”数组值。
I tried: 我试过了:
select *
from orders o
where json_value(details, '$.products[*].product') = '2';
but that didn't return anything. 但这没有回报任何东西。
I also tried json_table
, but that also seems to only take the first element from the array: 我也尝试过json_table
,但这似乎也只是从数组中获取第一个元素:
select *
from orders o,
json_table(o.details, '$' columns (product_id integer path '$.products[*].product')) t
where t.product_id = 2;
But that didn't show anything. 但这没有任何表现。 Apparently the "star expansion" in the " array_step " doesn't expand the values in the json_table
显然,“ array_step ”中的“星形扩展”不会扩展json_table
的值
So my question is: 所以我的问题是:
how can I (based on the above sample data) retrieve all orders where the product with the number 2 has been ordered? 我如何(根据上面的示例数据)检索订购了数字2的产品的所有订单?
I am essentially looking for the equivalent to this Postgres query: 我基本上寻找相当于这个Postgres查询:
select *
from orders
where details @> '{"products": [{"product": 2}] }';
I do not have any installation of oracle available right now but I believe that the first string in json_table should be the path to the array which we want to produce rows from. 我现在没有任何oracle安装,但我相信json_table中的第一个字符串应该是我们想要从中生成行的数组的路径。 Then inside COLUMNS , the path should be relative to the array, not the root. 然后在COLUMNS内部,路径应该是相对于数组而不是根。
Try this: 尝试这个:
select *
from orders o,
json_table(o.details, '$.products[*]'
columns (
product_id integer path '$.product'
)
) t
where t.product_id = 2;
In 12.2 you can do this with JSON_EXISTS 在12.2中,您可以使用JSON_EXISTS执行此操作
SQL> WITH ORDERS as
2 (
3 select 1 as ID, '{"products": [{ "product": 1, "quantity": 5}, {"product": 2, "quantity": 1}], "delivery_address": "My hometown"}' as DETAILS
4 from dual
5 union all
6 select 2 as ID, '{"products": [{ "product": 42, "quantity": 1}, {"product": 10, "quantity": 2}], "comment": "Your website is too slow"}' as DETAILS
7 from dual
8 union all
9 select 3 as ID, '{"products": [{ "product": 543, "quantity": 1}], "discount": "15"}' as DETAILS
10 from dual
11 union all
12 select 4 as ID, '{"products": [{ "product": 738, "quantity": 12}], "discount": "32"}' as DETAILS
13 from dual
14 )
15 select *
16 from ORDERS
17 where JSON_EXISTS(DETAILS,'$?(@.products.product == $PRODUCT)' passing 2 as "PRODUCT")
18 /
ID
----------
DETAILS
--------------------------------------------------------------------------------
1
{"products": [{ "product": 1, "quantity": 5}, {"product": 2, "quantity": 1}], "d
elivery_address": "My hometown"}
SQL>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.