我有一个过滤器,用户可以选择 ,包含等操作...
WHERE lower(bubu) = 'xoxo'
SQL WHERE条件。WHERE bubu ILIKE '%xoxo%'
SQL WHERE条件。现在我添加了负面变体 - 不是,不包含等等。我不想从头开始重写WHERE条件,所以我在前置NOT
已经存在的:
WHERE NOT lower(bubu) = 'xoxo'
SQL WHERE条件。WHERE NOT bubu ILIKE '%xoxo%'
SQL WHERE条件。然而,有一个问题。如果 bubu 是一个可以为空的字段并且它实际上有NULL,那么负WHERE条件不会选择它,尽管从人的角度来看(而不是SQL),NULL值应该满足 bubu不是xoxo 过滤器。
我通过修改原始的正WHERE条件解决了这个问题:
WHERE (lower(bubu) = 'xoxo' AND bubu IS NOT NULL)
SQL WHERE条件。然后,否定产生:
WHERE NOT (lower(bubu) = 'xoxo' AND bubu IS NOT NULL)
SQL WHERE条件。这次正确地拾取了NULL值。同样的问题是包含过滤器。
是否有一个更优雅的解决方案来解决人类如何处理NULL以及SQL如何处理它之间的这种不一致?
我正在使用PostgreSQL 9.2,我不介意拥有特定于此数据库的解决方案。
P.S。
请注意,我希望否定表达式的格式为非正面。
答案 0 :(得分:1)
我认为您应该能够使用COALESCE将NULL转换为空字符串:
-- These skip skips NULLs
lower(coalesce(bubu, '')) = 'xoxo'
coalesce(bubu, '') ilike '%xo%'
-- These will find NULLs
not lower(coalesce(bubu, '')) = 'xoxo'
not coalesce(bubu, '') ilike '%xo%'
当然,如果您正在搜索空字符串,这种技巧会遇到问题,在这种情况下,您需要一个上下文相关的标记值,以便您可以智能地选择一些与您的搜索字词不匹配的内容
答案 1 :(得分:0)
对于=
运算符,您可以使用is [not] distinct from
构造
WHERE (lower(bubu) is not distinct from 'xoxo')
http://www.postgresql.org/docs/9.2/static/functions-comparison.html