WHERE 子句中的 PostgreSQL 多元组选择
PostgreSQL multiple tuples selection in WHERE clause
我有这个 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');
我想根据元组 (keyword,category)
检索结果。所以基本上,通过一个简单的元组,我有以下查询:
SELECT result FROM myTable WHERE keyword LIKE '%a%' AND category = 'A';
-- returns 10,200 as expected
但我可以拥有任意数量的元组。为几个元组扩展此查询 returns 错误结果:
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。
第一个元组 return 10,200,第二个元组 200。在这种情况下,我只想 return 200。
在这样的评论中使用 OR 作为建议:
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR ( keyword LIKE '%Superman%' AND category = 'B');
returns 10,200,但这不是我想要的...
你快到了:
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR (keyword LIKE '%Superman%' AND category = 'B');
它的作用是:如果关键字像“%a%”和类别 = 'A',或者如果关键字像“%supaerman%”和类别 =,它 return 是行'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
到 return 一行(除其他事项外,该行中的类别必须是 'A' 和 'B'。由于它们不能同时存在,因此没有行returned.
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(...) 查询 return 所有类别等于 'B' 的行,其中关键字不包含 'Superman'(当然还有来自他 OR 之前的情况)。 ;)
我想你也可以看看文档SIMILAR TO
你可以这样做
SELECT * from myTable where keyword SIMILAR TO '%(oo|ba)%' and category SIMILAR TO '(A)';
您似乎要找的东西叫做关系划分。该任务可以表述为:
查找至少有一行符合这些条件的结果:
keyword LIKE '%a%' AND category = 'A'
和至少一行符合这些其他条件:
keyword LIKE '%Superman%' AND category = 'B'
条件的快速解决方案 returning DISTINCT
结果:
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';
但是由于您的过滤器可以为每个结果 return 多行,因此其中之一将 更快:
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);
或者:
SELECT result
FROM (
SELECT DISTINCT result
FROM tbl
WHERE keyword LIKE '%a%' AND category = 'A'
) t
WHERE EXISTS (
SELECT 1
FROM tbl
WHERE result = t.result
AND keyword LIKE '%Superman%' AND category = 'B'
);
SQL Fiddle.
我们在这个相关问题下汇集了一系列查询技术:
- How to filter SQL results in a has-many-through relation
我有这个 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');
我想根据元组 (keyword,category)
检索结果。所以基本上,通过一个简单的元组,我有以下查询:
SELECT result FROM myTable WHERE keyword LIKE '%a%' AND category = 'A';
-- returns 10,200 as expected
但我可以拥有任意数量的元组。为几个元组扩展此查询 returns 错误结果:
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。 第一个元组 return 10,200,第二个元组 200。在这种情况下,我只想 return 200。
在这样的评论中使用 OR 作为建议:
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR ( keyword LIKE '%Superman%' AND category = 'B');
returns 10,200,但这不是我想要的...
你快到了:
SELECT distinct result FROM myTable
WHERE ( keyword LIKE '%a%' AND category = 'A')
OR (keyword LIKE '%Superman%' AND category = 'B');
它的作用是:如果关键字像“%a%”和类别 = 'A',或者如果关键字像“%supaerman%”和类别 =,它 return 是行'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
到 return 一行(除其他事项外,该行中的类别必须是 'A' 和 'B'。由于它们不能同时存在,因此没有行returned.
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(...) 查询 return 所有类别等于 'B' 的行,其中关键字不包含 'Superman'(当然还有来自他 OR 之前的情况)。 ;)
我想你也可以看看文档SIMILAR TO
你可以这样做
SELECT * from myTable where keyword SIMILAR TO '%(oo|ba)%' and category SIMILAR TO '(A)';
您似乎要找的东西叫做关系划分。该任务可以表述为:
查找至少有一行符合这些条件的结果:
keyword LIKE '%a%' AND category = 'A'
和至少一行符合这些其他条件:
keyword LIKE '%Superman%' AND category = 'B'
条件的快速解决方案 returning DISTINCT
结果:
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';
但是由于您的过滤器可以为每个结果 return 多行,因此其中之一将 更快:
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);
或者:
SELECT result
FROM (
SELECT DISTINCT result
FROM tbl
WHERE keyword LIKE '%a%' AND category = 'A'
) t
WHERE EXISTS (
SELECT 1
FROM tbl
WHERE result = t.result
AND keyword LIKE '%Superman%' AND category = 'B'
);
SQL Fiddle.
我们在这个相关问题下汇集了一系列查询技术:
- How to filter SQL results in a has-many-through relation