「空またはnull値」をチェックする最良の方法


176

Postgres sqlステートメントで値がnullまたは空の文字列であるかどうかを確認する最良の方法は何ですか?

値は長い式になる可能性があるため、チェックして1回だけ書き込むことが望ましいです。

現在私は使用しています:

coalesce( trim(stringexpression),'')=''

しかし、それは少し醜く見えます。

stringexpressionであってもよいchar(n)列または含む発現char(n)末尾のスペースの列を。

最善の方法は何ですか?


3
charパディング(および結果として生じるスペースの浪費)のため、ほとんどの場合、使用は間違った選択です。しかし、それとは別に、もっと良い解決策があるとは思いません。
a_horse_with_no_name 2014年

なぜ醜いのですか?論理的で読みやすい。
klin

1
@a_horse_with_no_name:あると思います。
Erwin Brandstetter、2014年

回答:


283

式のstringexpression = ''結果は次のとおりです。

TRUE   ...のために''(またはのための任意のデータ型のスペースのみで構成される文字列char(n)
NULL   ..ためのNULL
FALSE 何かのため..

したがって、stringexpressionnullまたは空である」を確認するに

(stringexpression = '') IS NOT FALSE

または逆のアプローチ(読みやすいかもしれません):

(stringexpression <> '') IS NOT TRUE

以下のために働く任意の文字タイプを含みますchar(n)比較演算子に関するマニュアル。

またはtrim()、なしで元の式を使用します。これは、コストのかかるノイズchar(n)(下記を参照)、または他の文字タイプでは正しくありません。スペースのみで構成される文字列は、空の文字列として渡されます。

coalesce(stringexpression, '') = ''

しかし、上部の表現はより高速です。

反対のアサーションはさらに簡単です:stringexpressionがNULLでも空でもない」

stringexpression <> ''

char(n)

これはデータ型に関するものでchar(n)、以下の略ですcharacter(n)。(char/ characterのための短いchar(1)/ character(1)。)その使用はされてのPostgresに落胆

ほとんどの状況で、textまたはcharacter varying代わりに使用する必要があります。

混同しないでくださいchar(n)、他の有用な文字タイプでvarchar(n)varchartextまたは"char"(二重引用符付き)。

空の文字列だけのスペースからなる他の文字列とは異なるではありません。これらはすべて、型の定義ごとにn個のスペースに折りたたまれます。論理的には、上記の式も同様に機能します。これは(他の文字タイプでは機能しません)これらと同じです。char(n)char(n)char(n)

coalesce(stringexpression, '  ') = '  '
coalesce(stringexpression, '') = '       '

デモ

空の文字列にキャストは、スペースの任意の文字列に等しいですchar(n)

SELECT ''::char(5) = ''::char(5)     AS eq1
     , ''::char(5) = '  '::char(5)   AS eq2
     , ''::char(5) = '    '::char(5) AS eq3;

結果:

 eq1 | eq2 | eq3
 ----+-----+----
 t   | t   | t

「nullまたは空の文字列」かどうかをテストしますchar(n)

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);

結果:

stringexpression | base_test | test1 | test2 | 合体1 | 合体2 | 合体3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 foo | f | f | f | f | f | f
                  | t | t | t | t | t | t
                  | t | t | t | t | t | t
 null              | null       | t | t | t | t | t

「nullまたは空の文字列」かどうかをテストしますtext

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in a sane character types
   , (NULL)
   ) sub(stringexpression);

結果:

stringexpression | base_test | test1 | test2 | 合体1 | 合体2 | 合体3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 foo | f | f | f | f | f | f
                  | t | t | t | t | f | f
                  | f | f | f | f | f | f
 null              | null       | t | t | t | t | f

ここに db <> fiddle
古いsqlfiddle

関連:


2
@a_horse_with_no_name:OPはを要求しますbest way to check if value is null or empty stringtrim()そしてちょうど必要はない-コールは(比較的)高価です。char(n)「空の文字列」についてさらに追加しました。
Erwin Brandstetter 2014年

1
スペースのみを含む文字列式はと等しいと書いた''。トリムを外しcoalesce(stringexpression,'')=''て確認に使用できますか?これはあなたの答えに比べて私には読みやすく見えます。
Andrus

1
@Andrus:はい、できます。私はそれとさらにいくつかを答えに追加しました。
Erwin Brandstetter 2014年

3
select coalesce(' ', '') = '' falseを返します。したがって、TRIM()が必要です
Andrus

1
しかし、coalesce(' '::char(5), '') = ''そうではありません。いずれの場合も、上位2つの式のいずれかを使用します。これは、どの文字タイプでも機能し、最も高速でクリーンです。
Erwin Brandstetter 2014年

46

nullと空を確認するには:

coalesce(string, '') = ''

null、空、スペースをチェックするには(文字列をトリム)

coalesce(TRIM(string), '') = ''

3
私はこの答えのこの単純さ/明快さが好きです。
stwr667

12

文字列の長さのチェックも機能し、コンパクトです。

where length(stringexpression) > 0;

NULLケースについてこれを確認しましたか?
フリンシュ

1
はい、そうしました。空またはnullの文字列フィールドは返しません。
yglodt

空の値のみをチェックする必要がある場合は、これを試してください-> where length(stringexpression) = 0;。これは私にとってはうまくいきます。
Kushan Gunasekera

2

後続のスペースが空である可能性がある場合は、おそらくより良い解決策はありません。COALESCEあなたのような問題のためだけです


1

人々が使っているのを見たのはstringexpression > ''です。これは最速ではないかもしれませんが、たまたま最短の1つです。

MS SQLとPostgreSQLで試してみました。



0

NULL可能フィールドを比較するための優先される方法は、NULLIF(nullablefield、:ParameterValue)IS NULL AND NULLIF(:ParameterValue、nullablefield)IS NULLです。これは厄介ですが、一般的に使用されますが、場合によっては結合が不可能です。

NULLIFの2番目の逆の使用法は、最初のパラメーターがnullの場合、「NULLIF(nullablefield、:ParameterValue)IS NULL」は常に「true」を返すためです。


0

データベースに多数のレコードがある場合、null check時間がかかる可能性がある場合は、次のようなさまざまな方法でnullチェックを使用できます。1)where columnname is null 2)where not exists() 3)WHERE (case when columnname is null then true end)


0

答えの多くは最も短い方法であり、列にnullがたくさんある場合は必ずしも最良の方法ではありません。チェックを分割すると、オプティマイザは他の条件で作業する必要がないため、チェックをより速く評価できます。

(stringexpression IS NOT NULL AND trim(stringexpression) != '')

最初の条件が偽であるため、文字列比較を評価する必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.