... I'm okay accepting answers that can run on PostgreSQL. (I want to
learn if there is a smart way of writing this type of queries without "brute force")
There is a "smart way" in Postgres, with sorted arrays.
Integer
For integer
values use sort_asc()
of the additional module intarray
.
SELECT * FROM tbl
WHERE sort_asc(ARRAY[id1, id2, id3]) = '{1,2,3}' -- compare sorted arrays
Works for any number of elements.
Other types
As clarified in a comment, we are dealing with strings.
Create a variant of sort_asc()
that works for any type that can be sorted:
CREATE OR REPLACE FUNCTION sort_asc(anyarray)
RETURNS anyarray LANGUAGE sql IMMUTABLE AS
'SELECT array_agg(x ORDER BY x COLLATE "C") FROM unnest($1) AS x';
Not as fast as the sibling from intarray
, but fast enough.
- Make it
IMMUTABLE
to allow its use in indexes.
- Use
COLLATE "C"
to ignore sorting rules of the current locale: faster, immutable.
- To make the function work for any type that can be sorted, use a polymorphic parameter.
Query is the same:
SELECT * FROM tbl
WHERE sort_asc(ARRAY[val1, val2, val3]) = '{bar,baz,foo}';
Or, if you are not sure about the sort order in "C" locale ...
SELECT * FROM tbl
WHERE sort_asc(ARRAY[val1, val2, val3]) = sort_asc('{bar,baz,foo}'::text[]);
Index
For best read performance create a functional index (at some cost to write performance):
CREATE INDEX tbl_arr_idx ON tbl (sort_asc(ARRAY[val1, val2, val3]));
SQL Fiddle demonstrating all.