I try to write a query where I select rows based one a LIKE
pattern that has to match none of the entries of an array. What I have is the current one
SELECT * FROM mytable WHERE
NOT (EXISTS (SELECT * from unnest(a) WHERE unnest LIKE '%XYZ%' )))
Actually what I want is pairs - so it is more like
SELECT * FROM mytable WHERE
NOT (
(EXISTS (select * from unnest(a) as A, unnest(b) as B WHERE A||B LIKE '%xyz%abc%' )) OR
(EXISTS (select * from unnest(a) as A, unnest(b) as B WHERE A||B LIKE '%abc%xyz%' ))
)
This works for me but looks rather unwieldy. Is there prettier/more efficient solution to this? What I am find the most irksome is the SELECT
as part of the WHERE
clause to unroll arrays.
some points:
- In my case
xyz
andabc
will not appear together as substrings in a single array entry (e.g. nothing likexyzblaabc
exists) - Both arrays have exactly the same number of elements (they are actually derived from another query)
- no null elements (but even if that would still work as then I don't have a pair of
abc
andxyz
)
Edit:
Clarification: a row contains A as {rxyz,foo, bar}
and B as {other, abc, this}
should not be returned as it contains the rxyz
in one array and abc
in the other
Example:
SELECT * FROM(
SELECT *
FROM (select 1 as ID, '{rxyz,foo,bar}'::varchar[] as a, '{abc,other,this}'::varchar[] as b) row1 UNION
SELECT *
FROM (select 2 as ID, '{rxyz,foo,bar}'::varchar[] as a, '{other,rabc,this}'::varchar[] as b) row1 UNION
SELECT *
FROM (select 3 as ID, '{else,foo,bar}'::varchar[] as a, '{abc,other,this}'::varchar[] as b) row2
) mytable
WHERE
NOT (
(EXISTS (select * from unnest(a) as A, unnest(b) as B WHERE A||'-|-'||B LIKE '%xyz%-|-%abc%' OR B||'-|-'||A LIKE '%xyz%-|-%abc%' )))
returns only row3. In my use case I can guaranty that -|-
is not part of either list making it possible to separate these.