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子句中,
。。。