I have this table:
create table myTable (keyword text, category text, result text
, primary key (keyword,category));
insert into myTable values
('foo', 'A', '10'),
('bar', 'A', '200'),
('baz', 'A', '10'),
('Superman', 'B', '200'),
('Yoda', 'B', '10'),
('foo', 'C', '10');
I want to retrieve results according to tuples (keyword,category)
. So basically, with one easy tuple I have the following query:
SELECT result FROM myTable WHERE keyword LIKE '%a%' AND category = 'A';
-- returns 10,200 as expected
But I can have as many tuples as I want. Extending this query for several tuples returns bad results:
SELECT result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
AND ( keyword LIKE '%Superman%' AND category = 'B');
-- expected 200; but returned no rows...
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR ( NOT(keyword LIKE '%Superman%') AND category = 'B');
-- expected 10; but returned 10,200...
That's pretty logical because PostgreSQL does not follow the operator order and parenthesis.
Only OR
clauses are working. If I had only OR
clauses, I'd use something like this:
SELECT result FROM myTable
INNER JOIN (VALUES
('foo','C'),
('Superman', 'B')
) t(keyword,category) USING (keyword,category); -- 10,200 as expected
But it works only for OR
and for strict equality. In my case I want to use a LIKE
equality and I want to use AND
, OR
, AND NOT
and OR NOT
between the different tuples.
More precisely, when I write:
SELECT result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
AND ( keyword LIKE '%Superman%' AND category = 'B');
-- expected 200; but returned no row
I mean I want the INTERSECTION of results obtained by the two clauses. The first tuple return 10,200 and the second one 200. I want to return only 200 in this case.
Using an OR as suggesting in comments like this:
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR ( keyword LIKE '%Superman%' AND category = 'B');
returns 10,200, but that's not that I want ...