A Quick Look at the && Operator in PostgreSQL

We can use the && operator in PostgreSQL to check two arrays for any overlapping elements.

We include an array on each side of the operator to compare them, and the result is a Boolean value that indicates whether or not there’s any overlap. A result of True (or t) indicates that there’s an overlap, while False (or f) indicates there’s no overlap.

Example

Here’s a simple example to demonstrate:

SELECT ARRAY[ 3, 7, 9 ] && ARRAY[ 2, 6, 7 ];

Result:

t

This query returns t (true) because there is an overlap between the two arrays. Both arrays include 7 as an element, which means there’s an overlap.

Here’s what happens where there’s no overlap:

SELECT ARRAY[ 'Cat', 'Dog' ] && ARRAY[ 'Horse', 'Buffalo' ];

Result:

f

We get f for false as expected.

A Database Example

Suppose we have a table with the following data:

SELECT * FROM t1;

Result:

 c1 |     c2     |              c3               
----+------------+-------------------------------
1 | {1,2,3} | {{1,2,3},{4,5,6}}
2 | {4,5,6} | {{7,8,9},{10,11,12}}
3 | {7,8,9} | {{7,13,14},{15,16,17}}
4 | {10,11,12} | {{100,200,300},{400,500,600}}

We can check each row for overlaps between the arrays in the c2 and c3 columns:

SELECT 
    c2,
    c3,
    c2 && c3 AS "True/False"
FROM t1;

Result:

     c2     |              c3               | True/False 
------------+-------------------------------+------------
{1,2,3} | {{1,2,3},{4,5,6}} | t
{4,5,6} | {{7,8,9},{10,11,12}} | f
{7,8,9} | {{7,13,14},{15,16,17}} | t
{10,11,12} | {{100,200,300},{400,500,600}} | f

We can use a WHERE clause to filter the result to just those rows that have an overlap:

SELECT * FROM t1
WHERE c2 && c3;

Result:

 c1 |   c2    |           c3           
----+---------+------------------------
1 | {1,2,3} | {{1,2,3},{4,5,6}}
3 | {7,8,9} | {{7,13,14},{15,16,17}}

Negate the Operator

We can negate the condition with the NOT operator:

SELECT * FROM t1
WHERE NOT c2 && c3;

Result:

 c1 |     c2     |              c3               
----+------------+-------------------------------
2 | {4,5,6} | {{7,8,9},{10,11,12}}
4 | {10,11,12} | {{100,200,300},{400,500,600}}

Compare a Column to an Array Constant

We can also compare a column to an array constant:

SELECT * FROM t1
WHERE c2 && '{5}';

Result:

 c1 |   c2    |          c3          
----+---------+----------------------
2 | {4,5,6} | {{7,8,9},{10,11,12}}

Another way to build the array is with the ARRAY constructor:

SELECT * FROM t1
WHERE c2 && ARRAY[5];

Result:

 c1 |   c2    |          c3          
----+---------+----------------------
2 | {4,5,6} | {{7,8,9},{10,11,12}}

Non Arrays

If either of the expressions are non arrays we get an error:

SELECT * FROM t1
WHERE c1 && c3;

Result:

ERROR:  operator does not exist: integer && integer[]
LINE 2: WHERE c1 && c3;
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.

In this case I replaced c2 with c1, but c1 is not an array column and so I got the error.

NULL Expressions

If any of the expressions resolve to NULL, then NULL is returned:

SELECT ARRAY[ 3, 7, 9 ] && NULL;

Result:

NULL

Doing this with the database query results in an empty result set:

SELECT * FROM t1
WHERE NULL && c3;

Result:

 c1 | c2 | c3 
----+----+----
(0 rows)