我在PostgreSQL中有一个JSONB
对象:
'{"cars": ["bmw", "mercedes", "pinto"], "user_name": "ed"}'
我正尝试在WHERE
的{{1}}子句中使用其中“cars”数组中的值:
SELECT
这将正确返回值1,2和3 - 请参阅本文底部的表格设置。
目前,在我的功能中我这样做:
SELECT car_id FROM cars WHERE car_type IN ('bmw', 'mercedes', 'pinto');
但是,(1) Extract the "cars" array into a variable `v_car_results`.
(2) Use that variable in the `WHERE` clause.
Pseudo code:
DECLARE v_car_results TEXT
BEGIN
v_car_results = '{"cars": ["bmw", "mercedes", "pinto"], "user_name": "ed"}'::json#>>'{cars}';
-- this returns 'bmw', 'mercedes', 'pinto'
SELECT car_id FROM cars WHERE car_type IN ( v_car_results );
END
语句不返回任何行。我知道它正在读取这3种车型作为单类型。 (如果我只在“cars”元素中包含一个SELECT
,则查询工作正常。)
我如何将这些值视为car_type
子句中的数组?
我尝试过其他一些事情:
WHERE
条款。
施放的各种尝试。
这些查询:
ANY
感觉就像我想念的那样简单。但是我在这个兔子洞里掉了下来。 (也许我甚至不应该使用SELECT car_id FROM cars
WHERE car_type IN (json_array_elements_text('["bmw", "mercedes", "pinto"]'));
...
WHERE car_type IN ('{"cars": ["bmw", "mercedes", "pinto"], "user_name": "ed"}':json->>'cars');
运算符?)
::json#>>
答案 0 :(得分:5)
假设当前的Postgres版本为9.5,因为它未被指定。
使用set-returns函数jsonb_array_elements_text()
(作为表函数!)和 join 结果:
cout << flush;
使用SELECT c.car_id
FROM jsonb_array_elements_text('{"cars": ["bmw", "mercedes", "pinto"]
, "user_name": "ed"}'::jsonb->'cars') t(car_type)
JOIN cars c USING (car_type);
从对象中提取JSON数组,并将生成的JSON数组(仍为数据类型jsonb->'cars'
)传递给该函数。 (操作员jsonb
也可以完成这项工作。)
除此之外:#>
不仅仅是一个运营商。它是对json(::json#>>
)的强制转换,后跟运算符::json
。你也不需要。
生成的类型#>>
可以方便地匹配您的列类型text
,因此我们不需要输入类型。并指定列名varchar(255)
以允许在连接条件中使用car_type
的语法缩写。
这种形式更短,更优雅,通常比使用USING
或IN ()
的替代品快一点 - 这也会起作用。您的尝试非常接近,但您需要使用 子查询 的变体。这可行:
= ANY()
或者,清洁:
SELECT car_id FROM cars
WHERE car_type IN (SELECT json_array_elements_text('["bmw", "mercedes", "pinto"]'));
详细说明:
相关: