Postgres:检查数组字段是否包含值?


78

我肯定这是一个重复的问题,因为答案在某处,但是在谷歌搜索10分钟后我一直找不到答案,因此我呼吁编辑人员不要关闭它可能对其他人有用的基础。

我正在使用Postgres 9.5。这是我的桌子:

        Column          │           Type            │                                Modifiers
─────────────────────────┼───────────────────────────┼─────────────────────────────────────────────────────────────────────────
 id                      │ integer                   │ not null default nextval('mytable_id_seq'::regclass)
 pmid                    │ character varying(200)    │
 pub_types               │ character varying(2000)[] │ not null

我想在中找到所有带有“ Journal”的行pub_types

我找到了文档并用谷歌搜索,这是我尝试过的:

select * from mytable where ("Journal") IN pub_types;
select * from mytable where "Journal" IN pub_types;
select * from mytable where pub_types=ANY("Journal");
select * from mytable where pub_types IN ("Journal");
select * from mytable where where pub_types contains "Journal";

我已经扫描了postgres数组文档,但是看不到如何运行查询的简单示例,并且StackOverflow问题似乎都基于更复杂的示例。

Answers:


137

这应该工作:

select * from mytable where 'Journal'=ANY(pub_types);

即语法为<value> = ANY ( <array> )。还要注意,postresql中的字符串文字是用单引号引起来的。


非常感谢你!
理查德

@redneb如果我要检查“数组”字段中是否包含数组中的项,该怎么办?
亚伦

我越来越ERROR: input of anonymous composite types is not implemented
巴蒂尔

一样<value> IN ( <array> )吗?
jallen0927

2
关于性能的这种语法呢?从mytable中选择*,其中pub_types @> array ['Journal':: text];
尼娜

43

使用ANY运算符,您只能搜索一个值。

例如,

select * from mytable where 'Book' = ANY(pub_types);

如果要搜索多个值,可以使用@>运算符。

例如,

select * from mytable where pub_types @> '{"Journal", "Book"}';

您可以指定喜欢的顺序。


22
@>均值包含该数组中的所有值。如果要搜索当前数组是否包含另一个数组中的任何值,可以使用&&select * from mytable where pub_types && '{"Journal", "Book"}';
jallen0927

1
我不知道这是否是版本,但是@>和&&在Postgres 9.6上对我的工作完全相同。他们都匹配列表中的任何项目。除了@>还匹配一个空列表'{}'。
Marcelus Trojahn

6

这为我工作:

select * from mytable
where array_to_string(pub_types, ',') like '%Journal%'

根据您的规范化需求,最好使用FK引用实现单独的表,因为这样可能会获得更好的性能和可管理性。


与标签类似,如果您不打算保留标签表或仅使用它的一个实体。
barnacle.m,

1
如果您有多个具有相同前缀的值,即“ Journal Entries”
Halfdan

1
OP表达问题的方式似乎是他想查找Journal出现在字符串中的任何位置。如果只想匹配“ Journal”一词的特定位置,则删除前导和尾随通配符(即%)。
Shane

1
尼斯-使我能够对数组进行ILIKE查询;谢谢!SELECT * FROM archive WHERE ARRAY_TO_STRING(kw, ',') ILIKE '%pLASt%';
维多利亚·斯图尔特

2

代替IN我们可以使用ANY强制转换为枚举数组的数组,例如:

create type example_enum as enum (
  'ENUM1', 'ENUM2'
);

create table example_table (
  id integer,
  enum_field example_enum
);

select 
  * 
from 
  example_table t
where
  t.enum_field = any(array['ENUM1', 'ENUM2']::example_enum[]);

或者我们仍然可以使用“ IN”子句,但是首先,我们应该“取消嵌套”它:

select 
  * 
from 
  example_table t
where
  t.enum_field in (select unnest(array['ENUM1', 'ENUM2']::example_enum[]));

示例:https//www.db-fiddle.com/f/LaUNi42HVuL2WufxQyEiC/0


-1

这对我有用

let exampleArray = [1, 2, 3, 4, 5];
let exampleToString = exampleArray.toString(); //convert to toString
let query = `Select * from table_name where column_name in (${exampleToString})`; //Execute the query to get response

我遇到了同样的问题,经过一个小时的努力,我才知道不应在查询中直接访问该数组。因此,我然后发现数据应该在自身的括号内发送,然后再次使用js中的toString方法将该数组转换为字符串。所以我通过执行上面的查询工作,并得到了我的预期结果


4
请务必在代码中添加说明。这将提高您的答案质量。
DaFois
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.