我们说我有一个简单的表,例如:
id_ | tags
---------------
0 | foo1, baz
1 | bar1, qux
id_
列的类型为SERIAL
,tags
列的类型为TEXT[]
(文本数组)。
为了使用tags
运算符搜索LIKE
列,我使用unnest
和DISTINCT ON
的组合,如下所示:
SELECT DISTINCT ON (id_) *
FROM (
SELECT unnest(tags) tag, *
FROM Records
) x
WHERE
(tag LIKE '%o%');
这很好用。查询返回行0
,就像它应该的那样。
现在,我试图找出一种反转查询的方法,以便它只返回与LIKE
表达式不匹配的行。我试过这个:
WHERE
(tag NOT LIKE '%o%');
但它似乎没有用......我的想法是这个查询应该仅返回行1
,但它返回两行。
我也尝试过子查询,例如像这样:
WHERE
(x.id_ NOT IN (SELECT id_ FROM Records WHERE tag like '%o%'));
但它仍会返回两行。
有谁知道如何解决这个问题?
答案 0 :(得分:2)
perl -i -pe 's/(\d+)/1+$1/e' VersionNumber
echo "bump version: `cat VersionNumber`"
git add VersionNumber
git commit --amend -m "bump version: `cat VersionNumber`"
只需要匹配一个标记。 like
必须与所有匹配。因此,汇总:
not like
或使用SELECT id_
FROM (SELECT unnest(tags) tag, *
FROM Records
) x
GROUP BY id_
HAVING SUM( (tag LIKE '%o%')::int) = 0;
:
bool_and()
答案 1 :(得分:2)
您可以使用ALL
来检查所有未通过标记的NOT LIKE '%o%'
是否使用Postgres的能力返回布尔值以进行比较表达式。
SELECT DISTINCT ON (id_) *
FROM records
WHERE true = ALL (SELECT tag NOT LIKE '%o%'
FROM unnest(tags) tag);
如果一个标记为LIKE '%o'
,则NOT LIKE '%o%'
将为该标记返回false
,并且不再为true
选择所有选定的值true = ALL (...)
成为true
。
ANY
和LIKE
轻松否定此内容:
SELECT DISTINCT ON (id_) *
FROM records
WHERE true = ANY (SELECT tag LIKE '%o%'
FROM unnest(tags) tag);
(或可能是true
或false
,= ALL
或= ANY
,(SELECT tag LIKE ...)
或(SELECT tag NOT LIKE ...)