ユーザーインターフェースによって値のリストが動的に設定されるフィルタリングの条件を形成する必要があることが多いです。また、欠損値(NULL)が結果に含まれるべきかどうかも管理する必要があります。このようなクエリは、大量のデータに対して高速に動作し、SQLのセマンティクスに関して正確でなければなりません。
IN、NOT IN条件とNULLのチェックを不適切に組み合わせると、予期しない結果をもたらすことがあります。なぜなら、SQLにおいて「NULL IN (...)」は常にUNKNOWNを返し、「NOT IN」はリストの要素のうちの1つがNULLの場合、空の結果を生じるからです。適切に条件を書かないと、大量のデータに対するパフォーマンスが急激に低下します。
正しい組み合わせは以下のようになります:
SELECT * FROM sales WHERE region IN ('Moscow','Samara') OR region IS NULL;
SELECT * FROM sales WHERE (region NOT IN ('Moscow','Samara') OR region IS NULL);
SELECT * FROM sales WHERE region NOT IN ('Moscow','Samara') AND region IS NOT NULL;
主要な特徴:
「WHERE field NOT IN ('a', NULL)」を確認するとどうなりますか?
結果は常に空になります。なぜなら、リスト内のNULLと比較されるすべての行はUNKNOWNを返し、すべてがフィルタリングされるからです。
コードの例:
SELECT * FROM test WHERE name NOT IN ('Ivan', NULL);
「IN (NULL,...)」はNULLの行に値を与えますか?
いいえ。NULL IN (...)の式は常にUNKNOWNを返し、TRUEを返さないからです。
大きな値のリストでのフィルタリングを高速化するにはどうすればよいですか?
インデックスを使用し、リストが大きい場合(何百または何千の値)には、一時テーブルとのJOINを適用することを推奨します。これは、長いINに比べてフィルタリングを高速化します。
分析レポートで「WHERE city NOT IN ('London', field_2, NULL)」を適用しました。結果は完全に空になり、誰も失われた行の原因を理解できませんでした。
長所:
短所:
CRMで顧客地域のリストを選択し、「欠損値を含む」ボタンを追加しました。フィルタのロジックは:
... WHERE city IN ('SPB','NNov') OR city IS NULL
長所:
短所: