如何在 PostgreSQL 12 上添加基于 select 值 (JSONB) 的条件?

How can I add condition based on select value (JSONB) on PostgreSQL 12?

我想筛选具有 gold 徽章的行。我正在使用 PG12 并且我使用了它的新路径功能。

澄清一下,我有一个 users_tbl table 这样的:

CREATE TABLE users_tbl (
   ID serial NOT NULL PRIMARY KEY,
   data jsonb NOT NULL
); 

让我们插入值:

INSERT INTO users_tbl (ID, data) values (1, '{"badges": ["gold", "silver"], "another_field": 1}');
INSERT INTO users_tbl (ID, data) values (2, '{"badges": ["silver"], "another_field": 3}');
INSERT INTO users_tbl (ID, data) values (3, '{"badges": ["gold"], "another_field": 4}');

现在当我这样查询时:

SELECT
  ID, jsonb_path_query("data", '$.badges') AS "badges"
FROM "users_tbl";

我得到了预期的结果:

+----+--------------------+
+ ID |       badges       +
+----+--------------------+
+ 1  | ["gold", "silver"] +
+----+--------------------+
+ 2  | ["silver"]         +
+----+--------------------+
+ 3  | ["gold"]           +
+----+--------------------+

现在列表只有 badge 个匹配 gold

SELECT
  jsonb_path_query("data", '$.badges') AS "badges"
FROM "users_tbl"
WHERE "badges" @> 'gold';

预期结果:

+----+--------------------+
+ ID |       badges       +
+----+--------------------+
+ 1  | ["gold", "silver"] +
+----+--------------------+
+ 3  | ["gold"]           +
+----+--------------------+

实际结果:

column "badges" does not exist 

如何针对 badges 添加条件?还是我做的事情不正确?我怎样才能得到预期的结果?

注意:PostgreSQL 12.

更新:

实际上在这个例子中我使用了一个简单的 jsonb 对象。实际上是这样的:

{
  "properties": {
    "badges": ["gold", "silver"]
  }
}

所以,badgesproperties

您可以使用 ? 运算符:

SELECT jsonb_path_query("data", '$.badges') AS "badges"
FROM "users_tbl"
WHERE "data" -> 'badges' ? 'gold';

注意:我不确定您是否需要此处 jsonb_path_query()。这是一个返回集合的函数,在您的上下文中似乎没有任何意义。您的查询可能是这样的:

SELECT "data" ->> 'badges' AS "badges"
FROM "users_tbl"
WHERE "data" -> 'badges' ? 'gold';

Demo on DB Fiddle:

| badges             |
| :----------------- |
| ["gold", "silver"] |
| ["gold"]           |

您可以使用包含运算符:

select
    jsonb_path_query(data, '$.badges') as badges
from users_tbl
where data->'badges' @> '"gold"';

jsonb_path_exists():

select
    jsonb_path_query(data, '$.badges') as badges
from users_tbl
where jsonb_path_exists(data, '$.badges ? (@[*] == "gold")')

How can I add condition against badges?

你真的不能。正如错误消息所说,它不是 table 的列 - 这就是您需要在 WHERE 子句中引用的内容。您不能使用选择别名来引用表达式的结果值。你可以重复一下

SELECT jsonb_path_query_first("data", '$.badges') AS "badges"
FROM "users_tbl"
WHERE jsonb_path_query_first("data", '$.badges') @> 'gold';

或使用 LATERAL 子查询:

SELECT badges
FROM "users_tbl", LATERAL jsonb_path_query("data", '$.badges') as badges
WHERE badges @> 'gold';