Postgres: check if array field contains value?

Postgresql

Postgresql Problem Overview


I'm sure this is a duplicate question in the sense that the answer is out there somewhere, but I haven't been able to find the answer after Googling for 10 minutes, so I'd appeal to the editors not to close it on the basis that it might well be useful for other people.

I'm using Postgres 9.5. This is my table:

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

I want to find all the rows with "Journal" in pub_types.

I've found the docs and googled and this is what I've tried:

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";

I've scanned the postgres array docs but can't see a simple example of how to run a query, and StackOverflow questions all seem to be based around more complicated examples.

Postgresql Solutions


Solution 1 - Postgresql

This should work:

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

i.e. the syntax is <value> = ANY ( <array> ). Also notice that string literals in postresql are written with single quotes.

Solution 2 - Postgresql

With ANY operator you can search for only one value.

For example,

SELECT * FROM mytable WHERE 'Book' = ANY(pub_types);

If you want to search multiple values, you can use @> operator.

For example,

SELECT * FROM mytable WHERE pub_types @> '{"Journal", "Book"}';

You can specify in which ever order you like.

Solution 3 - Postgresql

Although perhaps not the most efficient approach, this worked for me:

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

However, using the contains operater @> (see Sudharsan Thumatti's answer above) is probably a more performant choice but I have not done any benchmarks.

Depending on your normalization needs, it might be better to implement a separate table with a FK reference as you may get better performance and manageability.

Solution 4 - Postgresql

Instead of IN we can use ANY with arrays casted to enum array, for example:

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[]);

Or we can still use 'IN' clause, but first, we should 'unnest' it:

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

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichardView Question on Stackoverflow
Solution 1 - PostgresqlrednebView Answer on Stackoverflow
Solution 2 - PostgresqlSudharsan ThumattiView Answer on Stackoverflow
Solution 3 - PostgresqlShane KView Answer on Stackoverflow
Solution 4 - PostgresqlCepr0View Answer on Stackoverflow