1

ユーザーがiscontainsなどの操作を選択できるフィルターがあります...

  • bubu is xoxo はWHERE lower(bubu) = 'xoxo'SQL WHERE 条件に変換されます。
  • bubu にはWHERE bubu ILIKE '%xoxo%'、 SQL WHERE 条件に変換されるxoxo が含まれています。

今、私は負のバリアントを追加しました - is notdoes not containなど.. WHERE 条件を最初から書き直したくないので、NOT既存のものに追加します:

  • bubu is not xoxoWHERE NOT lower(bubu) = 'xoxo'は、 SQL WHERE 条件に変換されます。
  • WHERE NOT bubu ILIKE '%xoxo%'bubu には、 SQL WHERE 条件に変換される xoxo が含まれていません。

ただし、問題があります。bubuが null 許容フィールドであり、実際に NULL が含まれている場合負の WHERE 条件はそれを選択しませんが、(SQL ではなく) 人間の観点からは、NULL 値はbubu is not xoxoフィルターを満たす必要があります。

この問題を解決するには、元の正の WHERE 条件を次のように変更します。

  • bubu is xoxo はWHERE (lower(bubu) = 'xoxo' AND bubu IS NOT NULL)SQL WHERE 条件に変換されます。

次に、否定は次のようになります。

  • bubu is not xoxoWHERE NOT (lower(bubu) = 'xoxo' AND bubu IS NOT NULL)は、 SQL WHERE 条件に変換されます。

今度は NULL 値が正しく取得されます。同じ問題は、containsフィルターにもあります。

人間が NULL を処理する方法と SQL がそれを処理する方法との間のこの不一致を解決するためのより洗練されたソリューションはありますか?

私は PostgreSQL 9.2 を使用していますが、このデータベースに固有のソリューションを用意してもかまいません。

PS

否定的な表現をNOT Positiveの形式にしたいことに注意してください。

4

2 に答える 2

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

もちろん、空の文字列を検索している場合、この種のトリックは問題に遭遇します。そのような場合、検索語に一致しない可能性があるものをインテリジェントに選択できるように、状況依存のセンチネル値が必要になります。

デモ: http://sqlfiddle.com/#!12/8bbd2/3

于 2013-10-05T20:10:24.410 に答える