SELECT t.id, count(tag = ANY ('{a,b,c}') OR NULL) AS ic
FROM tbl t
, unnest(tags) x(tag)
GROUP BY 1;
That's an implicit JOIN LATERAL
. Rows with empty or NULL arrays are excluded. To include those, use:
LEFT JOIN unnest(tags) x(tag) ON TRUE
OTOH, if you are only interested in rows with at least one match you could pre-select with the overlap array operator &&
for better performance:
SELECT t.id, count(tag = ANY ('{a,b,c}') OR NULL) AS ic
FROM (SELECT * tbl WHERE tags && '{a,b,c}') t
, unnest(tags) x(tag)
GROUP BY 1;
&&
can be supported with a GIN index, which would make the difference for a big table.
More about the counting technique: