特定の文字列フィールドが空白でも null でもないレコードを探したかったので、SELECT ... FROM myTable WHERE x
空白文字列と null 文字列が false と評価されると仮定して、単純に と書きましたが、そうではないようです。
文字列「02306」は真ですが、「N06097EIP」は何らかの形で偽です。
どうしたの?
編集:回避策を認識しています。キャストがどのように機能するかを知りたいだけです。
これらの式では、文字列は最初に数値に変換されます。「02306」は2306に変換されます。これは>0であるため、と見なされますtrue
。「N06097EIP」(数字以外で始まる)は0に変換され、。として評価されfalse
ます。
次の結果を比較します。
select convert("N06097EIP",signed)
と
select convert("02306",signed)
ブール値のコンテキストでは、
WHERE x
式x
は整数値として評価されます。MySQLはBOOLEANを数値型と見なしていることに注意してください。
http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html
式がどのタイプであるかは関係ありませんx
。文書化された変換規則に従って、INTEGER型であるか、INTEGER型に変換されます。
最終的な結果として、式x
はNULL、整数ゼロ、または整数非ゼロのいずれかであると評価されます。
そして、それらは、NULL、FALSE、およびTRUEのブール「真実性」値に対応します。
'02306'
この文字列がゼロ以外の整数値2306に変換されるため、TRUEと見なされる理由があります。
'N06097EIP'
この文字列が整数値0に変換されるため、FALSEと見なされます。
簡単なテストケースを実行して検証するには、次のようにします。
SELECT IF( 0 = 'N06097EIP', 'is zero', 'is not zero')
SELECT 0 = 'N06097EIP'
あなたが観察する振る舞いは完全に予想されます。それはすべて非常に簡単です。規範的なパターンは、このタイプの評価を回避し、代わりに「回避策」を使用してブール値を返すためです。
シンタックス ショートカットを使用して、これを甘やかしすぎないようにしてください。少なくとも、あなたが何をしていたかを理解しなければならない次の開発者にとっては、常に困難です。
あなたが望むものを綴るだけです。
SELECT *
FROM myTable
WHERE x IS NOT NULL AND x <> '';
または、必要に応じて:
SELECT *
FROM myTable
WHERE COALESCE(x, '') <> '';