WHERE子句中的PostgreSQL多元组选择
我有这张桌子:WHERE子句中的PostgreSQL多元组选择,sql,postgresql,where,multiple-columns,relational-division,Sql,Postgresql,Where,Multiple Columns,Relational Division,我有这张桌子: 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'), (
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');
我想根据元组(关键字,类别)
检索结果。基本上,通过一个简单的元组,我有以下查询:
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不遵循运算符顺序和括号
只有或子句起作用。如果我只有或子句,我会使用如下内容:
SELECT result FROM myTable
INNER JOIN (VALUES
('foo','C'),
('Superman', 'B')
) t(keyword,category) USING (keyword,category); -- 10,200 as expected
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR ( keyword LIKE '%Superman%' AND category = 'B');
但它只适用于或和严格平等。在我的例子中,我想在不同的元组之间使用和和,或,和NOT
和或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
我的意思是,我想要两个子句得到的结果的交集。
第一个元组返回10200,第二个元组返回200。在这种情况下,我只想退200英镑
使用或作为以下评论中的建议:
SELECT result FROM myTable
INNER JOIN (VALUES
('foo','C'),
('Superman', 'B')
) t(keyword,category) USING (keyword,category); -- 10,200 as expected
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR ( keyword LIKE '%Superman%' AND category = 'B');
返回10200,但这不是我想要的…您就快到了:
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR (keyword LIKE '%Superman%' AND category = 'B');
它的作用是:如果关键字类似于“%a%”且类别为“a”,或者如果关键字类似于“%supaerman%”且类别为“B”,则返回行
您的查询执行了以下操作
SELECT result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
AND ( keyword LIKE '%Superman%' AND category = 'B'); -- expected 200; but returned no rows
要在此处返回一行(除其他外,该行中的类别必须是“a”和“B”。由于不能同时返回两行,因此未返回任何行
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..
本例中的NOT(…)使查询返回类别为“B”的所有行,其中关键字不包含“Superman”(当然还有他或之前的条件的结果)。;)我想您也可以查看文档
你可以这样做
SELECT * from myTable where keyword SIMILAR TO '%(oo|ba)%' and category SIMILAR TO '(A)';
您似乎正在寻找的是关系划分。这项任务的措辞可以是:
查找至少有一行与这些条件匹配的结果:
关键字,如“%a%”和category='a'
和至少有一行符合这些其他条件:
关键字,如“%Superman%”和category='B'
返回不同结果的条件的快速解决方案:
SELECT DISTINCT result
FROM tbl t1
JOIN tbl t2 USING (result)
WHERE t1.keyword LIKE '%a%' AND t1.category = 'A'
AND t2.keyword LIKE '%Superman%' AND t2.category = 'B';
但是,由于您的筛选器可以为每个结果返回多行,其中一行的速度会更快:
SELECT result
FROM (
SELECT DISTINCT result
FROM tbl
WHERE keyword LIKE '%a%' AND category = 'A'
) t1
JOIN (
SELECT DISTINCT result
FROM tbl
WHERE keyword LIKE '%Superman%' AND category = 'B'
) t2 USING (result);
或:
SQL小提琴。
在这个相关问题下,我们收集了大量的查询技术:
代码中是否有错误?也许您的意思是:从myTable中选择结果,其中(关键字像“%a%”和category='a')或(关键字像“%Superman%”和category='B')代码>。如果你有类别A和类别B,结果显然是什么都没有。至于像“%A%”这样的关键字和类别='A'
=>按预期返回bar和baz,而As没有(像“%Superman%”这样的关键字)和类别='B'
=>按预期返回yodaexpected@SimoKivist对于出错的第一个查询,我不需要OR,因为我不想得到第一个元组的每个结果加上第二个元组的每个结果。事实上,这是我需要的一个交叉点。@pidupuis预期为200;但是没有返回行>请尝试“谢谢”,但这不是OR。我指的是交叉路口。请参阅我的编辑。使用的解决方案似乎更好,因为它允许我使用而不是。您建议我如何将它与更多元组一起使用,这些元组交替使用和和或?(我可以在没有无限深度的嵌入式select的情况下组合几个EXISTS
和UNION
吗?@pidupuis:您已经知道如何实现或,将EXISTS
/NOT
添加到和/的WHERE子句中,
。。。