得到了一个搜索,我现在正在构建自己版本的查询过滤,例如布尔搜索。我的意思是,我可以做office +sweden
,这意味着sweden
必须存在。由于这个问题之外的原因,我们不能使用BOOLEAN搜索。
假设我有一个名为documents
的表,它上面有两列content
和notes
。当我在搜索栏中键入+office +sweden
时,我会执行类似的操作:
SELECT * FROM documents
WHERE (content LIKE '%office%' or notes LIKE '%office%') AND
(content LIKE '%sweden%' or notes LIKE '%sweden%')
到目前为止,这是完美的。这只会给我提供office
ANDsweden
位于content
或notes
中某个位置的文档。
现在我想做同样的事情,但要减去一个负数。例如,如果我搜索office -sweden
,我希望在contents
或notes
中获取包含office
且不包含sweden
的所有文档(是的,也使用通配符(。
我尝试了多种方法都没有让它正常工作。例如,我尝试过NOT LIKE
,但没有成功:
SELECT * FROM documents
WHERE (content LIKE '%office%' or notes LIKE '%office%') AND
(content NOT LIKE '%sweden%' or notes NOT LIKE '%sweden%')
感觉or
把这个搞砸了。我也试过使用AND NOT
SELECT * FROM documents
WHERE (content LIKE '%office%' or notes LIKE '%office%') AND NOT
(content LIKE '%sweden%' or notes LIKE '%sweden%')
我对AND NOT
寄予厚望,但这也没有像预期的那样奏效。
希望清楚我想做什么。使用LIKE
获取所有包含office
但不包含sweden
的文档。
解决方案
事实证明,查询本身并没有什么问题。我在查询中有更多可能为null的字段。我在问题中省略了这些字段,以便于理解。如果您有可以包含null
的字段,请确保像Gordon下面所说的那样处理它。
我使用IFNULL
操作符处理null
字段,如下所示:
SELECT * FROM documents
WHERE (content LIKE '%office%' or notes LIKE '%office%' or nullfield LIKE '%office%') AND
NOT (IFNULL(content, '') LIKE '%sweden%' or IFNULL(notes, '') LIKE '%sweden%' or IFNULL(nullfield, '') LIKE '%sweden%')
只需使用not like
:
SELECT *
FROM documents
WHERE (content LIKE '%office%' or notes LIKE '%office%') AND
(content NOT LIKE '%sweden%' and notes NOT LIKE '%sweden%');
或者如果你喜欢:
SELECT *
FROM documents
WHERE (content LIKE '%office%' or notes LIKE '%office%') AND
NOT (content LIKE '%sweden%' or notes LIKE '%sweden%');
需要注意的是:NOT LIKE
会像LIKE
一样忽略NULL
值。因此,如果值可以是NULL
,则需要将其考虑在内。