1

次のクエリを記述したところ、(私にとっては)驚きの結果が得られました。

Customer.where("satisfaction != ?","Very satisfied")

これは私が予想したよりもはるかに少ない値を返しました、そしてその理由は私の満足度列のデータベースのnull値であることがわかりました。必要なレコードを取得するには、次のクエリを作成する必要があります

Customer.where("satisfaction != ? or satisfaction is null","Very satisfied")

これは機能しますが、醜いので、もっと良い方法があることを望んでいます(特に、これらのクエリを動的に生成することを計画しているので、できるだけ単純にしたいので)。等しくない値とともにnull値を組み込む演算子はありますか?

私のデータベースは開発中のSQLite3と本番環境のPostgresqlです。

4

1 に答える 1

5

PostgreSQLでは、IS DISTINCT FROMを使用して、通常のNULLの問題を回避できます。

Customer.where('satisfaction is distinct from ?', 'Very satisfied')

SQLiteでは、明示的なISNULLチェックまたは同様に醜いCOALESCEで立ち往生していると思います。

Customer.where("coalesce(satisfaction, '') != ?", 'Very satisfied')

COALESCEは最初の非NULL引数に評価され、SQLiteとPostgreSQLの両方で機能します。'Very satisfied'空の文字列の代わりに、自分と一致しないものを使用できます。

PostgreSQL上にデプロイする場合は、SQLite上での開発を停止することを強くお勧めします。SQLiteのSQLの緩い解釈がPostgreSQLのより厳密な解釈と競合する場合、本番サーバーで悪い時間を求めているだけです。これを自分で行わないでください。同じデータベース(バージョン番号が含まれている場合)を使用して開発およびデプロイしてください

また、スキーマを再検討して、列にNOTNULL制約を追加できるかどうかを確認することもできますsatisfaction。明示的な'Unknown'文字列も同様に機能し、通常のNULLナンセンスを回避します。私は手動ですべてをデフォルトでNOTNULLに設定し、正当化できる場合にのみNULLを許可する傾向があります。

于 2012-10-22T04:48:02.117 に答える