加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

数组 – 在WHERE IN子句中使用JSONB数组中的值

发布时间:2020-12-13 16:01:53 所属栏目:百科 来源:网络整理
导读:我在PostgreSQL中有一个 JSONB对象: '{"cars": ["bmw","mercedes","pinto"],"user_name": "ed"}' 我试图在SELECT的WHERE子句中使用其中“cars”数组的值: SELECT car_id FROM cars WHERE car_type IN ('bmw','mercedes','pinto'); 这将正确返回值1,2和3 –
我在PostgreSQL中有一个 JSONB对象:

'{"cars": ["bmw","mercedes","pinto"],"user_name": "ed"}'

我试图在SELECT的WHERE子句中使用其中“cars”数组的值:

SELECT car_id FROM cars WHERE car_type IN ('bmw','mercedes','pinto');

这将正确返回值1,2和3 – 请参阅本文底部的表格设置.

目前,在我的功能中我这样做:

(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","user_name": "ed"}'::json#>>'{cars}';
            -- this returns 'bmw','pinto'
        SELECT car_id FROM cars WHERE car_type IN ( v_car_results );
    END

但是,SELECT语句不返回任何行.我知道它正在阅读这3种车型作为单一类型. (如果我只在“cars”元素中包含一个car_type,则查询工作正常.)

我如何将这些值视为WHERE子句中的数组?

我尝试过其他一些东西:

> ANY条款.
>各种铸造尝试.
>这些查询:

SELECT car_id FROM cars
WHERE car_type IN (json_array_elements_text('["bmw","pinto"]'));

...
WHERE car_type IN ('{"cars": ["bmw","user_name": "ed"}':json->>'cars');

这感觉就像是我想念的简单.但是我在这个兔子洞里掉了下来. (也许我甚至不应该使用:: json#>>运算符?)

表设置

CREATE TABLE cars (
   car_id SMALLINT,car_type VARCHAR(255)
);

INSERT INTO cars (car_id,car_type)
VALUES
  (1,'bmw'),(2,'mercedes'),(3,'pinto'),(4,'corolla');

SELECT car_id FROM cars
WHERE car_type IN ('bmw','pinto'); -- Returns Values : 1,2,3

解决方法

假设当前的Postgres版本为9.5,因为它没有指定.

使用set-returns函数jsonb_array_elements_text()(作为表函数!)并加入到结果中:

SELECT c.car_id
FROM   jsonb_array_elements_text('{"cars": ["bmw","user_name": "ed"}'::jsonb->'cars') t(car_type)
JOIN   cars c USING (car_type);

使用jsonb->’cars’从对象中提取JSON数组,并将生成的JSON数组(仍为数据类型jsonb)传递给该函数. (运算符#>也可以完成这项工作.)

旁边::: json#>>不仅仅是一个操作符.它是对json(:: json)的强制转换,后跟运算符#>>.你也不需要.

生成的类型文本可以方便地匹配列类型varchar(255),因此我们不需要类型转换.并指定列名car_type以允许在连接条件中使用USING的语法简写.

这种形式更短,更优雅,通常比使用IN()或= ANY()的替代品快一点 – 这也可以.您的尝试非常接近,但您需要带有子查询的变体.这可行:

SELECT car_id FROM cars
WHERE  car_type IN (SELECT json_array_elements_text('["bmw","pinto"]'));

或者,清洁:

SELECT car_id FROM cars
WHERE  car_type IN (SELECT * FROM json_array_elements_text('["bmw","pinto"]'));

详细说明:

> How to use ANY instead of IN in a WHERE clause with Rails?

有关:

> How to turn json array into postgres array?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读