PostgreSQL select * where column contains array value

Posted

技术标签:

【中文标题】PostgreSQL select * where column contains array value【英文标题】: 【发布时间】:2017-11-11 15:38:40 【问题描述】:

我有一个这样的 postgresql 数据库:

users
id     name     companyrestrictions
1      Bill     [3, 4]
2      Fred     [5, 6]

然后是每个公司的变量3 在这种情况下

所以我写了一个这样的查询:

SELECT * FROM users WHERE 3 = ANY(users.companyrestrictions)

但我收到以下错误: op ANY/ALL (array) 需要右侧的数组

公司限制的类型为jsonb

我做错了什么?

【问题讨论】:

正如错误所说:您不能在 JSONB 列上使用数组运算符。没有等效的函数来测试 JSONB 列内的数组内的元素。如果你只想存储一个数组,那你为什么不使用数组呢? 我没有看到 Postgres 的数组数据类型,有吗?它叫什么? postgresql.org/docs/current/static/arrays.html 【参考方案1】:

尝试<@ 包括operator:

左侧 JSON 路径/值条目是否包含在顶层 在正确的 JSON 值内?

SELECT * FROM users WHERE '3' <@ users.companyrestrictions

ANY 仅适用于数组

【讨论】:

返回此错误:operator does not exist: integer &lt;@ jsonb 你说得对,我没有注意到你把 3 变成了一个字符串,它现在可以工作了,即使你有这样的数组也可以工作吗[3, 33, 333] @Jordash:是的,它仍然可以工作。但请注意,这只适用于您的 JSON ***元素是一个数组。它不适用于像 "foo": [3, 5, 6] 这样的 JSON 太好了,是的,我️知道如何使用子级项目 感谢 cmets。 where '5' &lt;@ (b-&gt;'foo')::jsonb; 可用于将路径的非顶部元素变为顶部【参考方案2】:

最好将公司限制存储在另一个表中。 这正是 RDBMS 的用途。

如果你真的需要使用 JSON,你可能不得不解析它。在 postgres 中可能有一些 JSON 函数可用,但对于数组来说似乎很麻烦,您将无法使用 SQL 查询数据。

CREATE TABLE t_user (
    id   SERIAL                 PRIMARY KEY NOT NULL,
    name CHARACTER VARYING(256) NOT NULL
);

CREATE UNIQUE INDEX t_user_idx ON t_users(name);

CREATE TABLE t_company (
    id   SERIAL                 PRIMARY KEY NOT NULL,
    name CHARACTER VARYING(256) NOT NULL
);

CREATE UNIQUE INDEX t_company_idx ON t_company(name);

CREATE TABLE t_company_restriction (
    id         SERIAL  PRIMARY KEY NOT NULL,
    id_company integer NOT NULL REFERENCES t_company(id) ON DELETE CASCADE,
    id_user    integer NOT NULL REFERENCES t_user(id) ON DELETE CASCADE
);

CREATE UNIQUE INDEX t_company_restriction_idx ON t_company_restriction(id_company, id_user);

INSERT INTO t_user(name) VALUES ('Bill');
INSERT INTO t_user(name) VALUES ('Fred');

INSERT INTO t_company (name) VALUES ('Company 1');
INSERT INTO t_company (name) VALUES ('Company 2');
INSERT INTO t_company (name) VALUES ('Company 3');
INSERT INTO t_company (name) VALUES ('Company 4');

INSERT INTO t_company_restriction (id_user, id_company)
SELECT u.id, c.id FROM t_user u, t_company c
WHERE u.name = 'Bill' AND c.name = 'Company 1';

INSERT INTO t_company_restriction (id_user, id_company)
SELECT u.id, c.id FROM t_user u, t_company c
WHERE u.name = 'Bill' AND c.name = 'Company 2';

INSERT INTO t_company_restriction (id_user, id_company)
SELECT u.id, c.id FROM t_user u, t_company c
WHERE u.name = 'Fred' AND c.name = 'Company 3';

INSERT INTO t_company_restriction (id_user, id_company)
SELECT u.id, c.id FROM t_user u, t_company c
WHERE u.name = 'Fred' AND c.name = 'Company 4';

SELECT u.name
FROM   t_user u, t_company c, t_company_restriction cr
WHERE  c.name = 'Company 1'
AND    c.id = cr.id_company
AND    u.id = cr.id_user;

【讨论】:

以上是关于PostgreSQL select * where column contains array value的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL select * where column contains array value

PostgreSQL WHERE 子句

PostgreSQL WHERE 子句

我尝试在 laravel 上使用 postgresql 但找不到驱动程序(SQL: select * from "users" where "id" = 4 l

PostgreSQL-7-数据连接

用于有序字符串的 postgresql where 子句不起作用