質問

私はクエリの最適化に取り組んできましたが、SQLのOR演算子を常に使用してきたことに疑問を抱かせる状況に陥りました。 (SQL Server 2000も)

条件(WHERE)句が次のように見えるクエリがあります:

WHERE (Column1 = @Param1 or Column1 LIKE @Param1 + '%')
AND (@Param2 = '' OR Column2 = @Param2 OR Column2 LIKE @Param2 + '%')

今では、SQLのORが両方の式を評価することを常に理解しています。したがって、左の式でtrueと評価されたすべてのレコードが、右の式でtrueと評価されたすべてのレコードとともに返されます。例:

SELECT * FROM TABLE1
WHERE COL1 = 'Test' OR Col2 = 'Data'

これは、COL1が「Test」であるすべてのレコードと、Col2が「Data」であるすべてのレコードを返します

上記の例では、Column2条件を次のように変更しました。

AND(Column2 LIKE ISNULL(@Param2, '') + '%')

突然、0行が返されます。

ORがTRUEの結果を見つけるまで式を評価するだけであるか、2つの異なる結果が異なる結果を返す条件が存在するかと間違えられましたか?

役に立ちましたか?

解決

<!> quot; ORは、真の結果が見つかるまで式のみを評価します<!> quot;

必要なのはそれだけですが、それはあなたの問題ではありません(実際、これが元のケースであなたを救っていたものです)。 2つのクエリは実際には同等ではありません。

Column2にはNULLがtrueになることは決してない(Column2 LIKE ISNULL(@Param2, '') + '%')があると考えています-元のバージョンでは@Param2 = ''がこのケースをマスクしていました。 >

おそらく:

(ISNULL(Column2, '') LIKE ISNULL(@Param2, '') + '%')

NULLの3値のロジックを思い出してください:

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

しかし、あなたの最適化が本当に役立つかどうかはわかりません。

他のヒント

ORは、特に括弧で囲まれているため、すべてを網羅しているわけではありません。より大きなものは、WHERE X AND Yです。 XとY自体がORを使用するブール式であるという事実は重要ではありません。それらは別々に評価され、結果がAND演算子に渡されます。

[編集]:
もう一度読んで、私はあなたの質問を誤解したかもしれません。それを念頭に置いて、NULL LIKE '%'がNULLを返すため、他の答えを選択する必要があります。これは、この場合のfalseと同じです。代わりにこれを試してみてください:

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'

FYI、すべての条件が必ずしも評価されるわけではないことを確認するための非常に簡単な実験があります。

これをOracleで実行しましたが、SQL Serverでも同様の結果が得られると思います。

dev> select * from dual where 1=1 or 1/0 = 3;

D
-
X

ORの後の条件は、ゼロ除算エラーが発生するため、評価されてはなりません。

ブール演算子のこの処理は、一般的に<!> quot; short-circuiting <!> quot;として知られています。そして、知る限りでは、現代の言語ではかなり標準的です。 AND式にも適用できます。最初の条件がfalseの場合、式全体をTRUEにすることはできないため、2番目の条件を評価しても意味がありません。

詳細: http://en.wikipedia.org/wiki/Short-circuit_evaluation

とにかくケイドが言ったように、あなたの本当の問題はおそらくNULLの誤処理です。

MS-SQLは最初に左側を評価し、必要でない限り続行しません。

これはANDコネクターの場合と同じです。左側が評価され、falseの場合、右側は評価されません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top