如何在 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"]
}
}
所以,badges
在 properties
您可以使用 ?
运算符:
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';
| 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';
我想筛选具有 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"]
}
}
所以,badges
在 properties
您可以使用 ?
运算符:
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';
| 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';