2013-10-05 38 views
1

我有一個過濾器,用戶可以選擇操作,例如包含,等...否定SQL WHERE條件可空場

  • 布布是XOXO轉化爲WHERE lower(bubu) = 'xoxo' SQL WHERE條件。
  • bubu包含xoxo轉換爲WHERE bubu ILIKE '%xoxo%' SQL WHERE條件。

現在我已經添加了失活突變體 - 不含,等等。我不希望重寫了整個WHERE條件,所以我在前面加上NOT到已經存在的:

  • 布布不XOXO轉化爲WHERE NOT lower(bubu) = 'xoxo' SQL WHERE條件。
  • bubu不包含xoxo轉換爲WHERE NOT bubu ILIKE '%xoxo%' SQL WHERE條件。

但是,有一個問題。如果布爾是一個可爲空的字段,它實際上有NULL,那麼負的WHERE條件不會選擇它,儘管從人類的角度來看(與SQL相反)NULL值應該滿足布爾不是xoxo filter 。

我通過修改原有的積極解決這個問題WHERE條件是這樣的:

  • 布布是XOXO轉化爲WHERE (lower(bubu) = 'xoxo' AND bubu IS NOT NULL) SQL WHERE條件。

然後,否定收率:

  • 布布不XOXO轉換成WHERE NOT (lower(bubu) = 'xoxo' AND bubu IS NOT NULL) SQL WHERE條件。

而這一次NULL值正確拾取。同樣的問題是包含過濾器。

是否有更優雅的解決方案來解決人類如何處理NULL以及SQL如何處理這種不一致?

我使用PostgreSQL 9.2,我不介意有一個特定於此數據庫的解決方案。

P.S.

請注意,我想表達是形式不積極的。

回答

1

我想你應該能夠使用COALESCE到您的空值轉換爲空字符串閃避:

-- 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%' 

當然,如果您搜索空的條紋,這種欺騙會遇到問題在這種情況下,您需要一個上下文相關的標記值,以便您可以智能地選擇一些不可能與您的搜索詞匹配的內容。

演示:http://sqlfiddle.com/#!12/8bbd2/3

+0

+1。問題 - 使用COALESCE比我所做的更有效嗎? – mark

+0

我認爲COALESCE會相同或接近,以至於不會產生任何可衡量的差異。 –