web-dev-qa-db-ja.com

nullとの文字列連結は文字列全体を無効にするようです-Postgresでの望ましい動作ですか?

Postgresの場合:

select 'test' || null  returns null

そうでなければ「テスト」が返されると予想していました。

これは望ましい動作ですか?ヌル値との文字列連結は文字列全体を無効にするという奇妙なようです...

Pgドキュメントの参照: http://www.postgresql.org/docs/9.1/static/functions-string.html

「注:PostgreSQL 8.3より前では、これらのデータ型からテキストへの暗黙の強制が存在するため、これらの関数はいくつかの非文字列データ型の値も暗黙的に受け入れます。 、表9-6に示すように、少なくとも1つの入力が文字列型である限り、文字列連結演算子(||)は非文字列入力を受け入れます。他の場合は、必要に応じてテキストに明示的な強制を挿入します以前の動作を複製します。」

そのため、concat文字列関数の例を使用します。

concat(str "any" [、str "any" [、...]])textすべての引数を連結します。 NULL引数は無視されます。 concat( 'abcde'、2、NULL、22)>> abcde222

'||'でこの動作に慣れる必要があります連結またはこれは修正すべきものですか?

23
Reinsbrain

それはバグではなく、「奇妙」でもありません。

SQL標準では、nullnullを生成する式が必要です。これは文字列の連結に限定されず、計算にも適用されます。例:_42 * null_はnullを返します。

これは比較にも適用されます:_42 > null_はnullを生成します。したがって、比較は真でも偽でもありません。実際にはこれには「偽」の効果がありますが、それは偽ではなく「真ではない」ためです。ただし、このような式を否定すると、「true」ではなくnullが再び生成されます。

nullは非常に特殊なので、何かがnullかどうかを確認する唯一の方法は、演算子_IS NULL_または_IS NOT NULL_を使用することです。 _x is null_はtrueまたはfalseを生成し、nullを生成しないため、_is null_または_is not null_演算子を使用する式neverはnullを返します。上記の私の声明の例外です(それを指摘してくれたジョナサンに感謝します)。


nullの値に関するもう1つの(おそらく驚くべき)事実は、それらが集計関数によってどのように処理されるかです。 expression _4 + 5 + null_はnullを生成しますが、これらの(列)値に対するsum()は9を生成します。これは、集計ignorenull値。

次の表を考えます:

_    col1
--------
       1
       2
       3 
     null
_

sum(col1)は6を返し、avg(col1)は_2_を返します(合計= 6、追加された要素の数:3)

17

ドキュメントからの引用

すべての引数を連結します。 NULL引数は無視されます。

concat('abcde', 2, NULL, 22) 

戻り値

abcde222

詳細は ドキュメント をご覧ください

19

はい、望ましい動作です。

これは非常に便利な例です。 titlefirstnamenameaffix、およびlastnameの各フィールドにpersonテーブルがあるとします。フルネームを作成するには、これを行うだけです。

COALESCE(title || ' ', '') || firstname || COALESCE(' ' || nameaffix, '') || ' ' || lastname

その奇妙な振る舞いがなければ、フィールドがヌルかどうかに応じて適切な場所にスペースを配置する余裕が十分にあります。必須の名と姓を想定して、タイトルと名前の接辞の任意の組み合わせがカバーされます。

15
MyBrainHurts

SQLを教えてくれた人が言ったように、「NULLは「不明」を意味し、「ゼロ」を意味するのではなく、「空の文字列」は「不明」を意味します」。

それが望ましい動作である理由です。何かを未知の値と組み合わせた結果は未知です。

これは、新しい列を設計する際、およびそれらがNULL可能であることの意味を検討する価値もあります。

2
DatabaseShouter