【发布时间】:2015-03-31 09:13:57
【问题描述】:
我有这张桌子:
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');
我想根据元组(keyword,category)检索结果。所以基本上,通过一个简单的元组,我有以下查询:
SELECT result FROM myTable WHERE keyword LIKE '%a%' AND category = 'A';
-- returns 10,200 as expected
但我可以拥有任意数量的元组。将此查询扩展到几个元组会返回错误的结果:
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...
这很合乎逻辑,因为 PostgreSQL 不遵循运算符顺序和括号。
只有OR 子句有效。如果我只有 OR 子句,我会使用这样的:
SELECT result FROM myTable
INNER JOIN (VALUES
('foo','C'),
('Superman', 'B')
) t(keyword,category) USING (keyword,category); -- 10,200 as expected
但它仅适用于OR 和严格相等。在我的情况下,我想使用 LIKE 相等,并且我想在不同的元组之间使用 AND、OR、AND NOT 和 OR NOT。
更准确地说,当我写作时:
SELECT result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
AND ( keyword LIKE '%Superman%' AND category = 'B');
-- expected 200; but returned no row
我的意思是我想要两个子句获得的结果的 INTERSECTION。 第一个元组返回 10,200,第二个返回 200。在这种情况下,我只想返回 200。
像这样在 cmets 中使用 OR 作为建议:
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR ( keyword LIKE '%Superman%' AND category = 'B');
返回 10,200,但这不是我想要的 ...
【问题讨论】:
-
可能是代码错误?也许您的意思是:
SELECT result FROM myTable WHERE ( keyword LIKE '%a%' AND category = 'A') OR ( keyword LIKE '%Superman%' AND category = 'B');。如果您有 A 类 AND B 类,那么结果显然什么都没有。 -
至于
keyword LIKE '%a%' AND category = 'A'=> 按预期返回 bar 和 baz 而NOT(keyword LIKE '%Superman%') AND category = 'B'=> 按预期返回 yoda -
@SimoKivistö 对于第一个错误查询,我不想要 OR,因为我不想获得第一个元组的每个结果加上第二个元组的每个结果。事实上,这是我需要的一个 INTERSECTION。
-
@pidupuis for 预期 200;但没有返回任何行 > 试试this
标签: sql postgresql where multiple-columns relational-division