web-dev-qa-db-ja.com

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

PostgresのSQL文で値がnullか空文字列かをチェックする最も良い方法は何ですか?

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

現在使っています:

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

しかし、それは少し醜いように見えます。

stringexpressionは、char(n)列、または末尾にスペースを含むchar(n)列を含む式です。

最善の方法は何ですか?

125
Andrus

stringexpression = ''は次のようになります。

TRUE .. ''の場合(またはanyデータ型char(n)のスペースのみで構成される文字列の場合)
NULL .. NULLの場合
FALSE .. for anything else

"stringexpressionはNULLか空です"

(stringexpression = '') IS NOT FALSE

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

(stringexpression <> '') IS NOT TRUE

陳腐化したchar(n)を含む 任意の文字タイプ に有効です。これはほとんど役に立ちません。
比較演算子に関するマニュアルです。

またはtrim()には役に立たないchar(n)を使わずに、すでに持っている式を使ってください。他の文字タイプのテストでは、スペースのみで構成される文字列が含まれます。

coalesce(stringexpression, '') = ''

しかし、一番上の式は速いです。

反対の主張:"stringexpressionはNULLでも空でもない"はもっと簡単です:

stringexpression <> ''

char(n) について

このデータ型を varchar(n)varchartextまたは"char" (引用符付き)などの他の文字型と混同しないでください。これらはすべて有用なデータ型です。これは非常に限られた実用性を持つ時代遅れのデータ型についてのものです:char(n)、略して:character(n)。また、charcharacterchar(1)/character(1)の短縮形です(同じこと)。

char(n)では(他の文字列型とは異なります!)空の文字列はスペースのみからなる他の文字列と違いはありません。これらすべては、型の定義ごとにchar(n)内のnスペースに折りたたまれます。論理的には、これはchar(n)でも機能します。

coalesce(stringexpression, '') = ''

これらと同じくらい(他の文字タイプではうまくいきません):

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  

char(n)で "null or empty string"をテストします。

SELECT stringexpression 
      ,stringexpression = ''                    AS simple_test
      ,(stringexpression = '')  IS NOT FALSE    AS test1
      ,(stringexpression <> '') IS NOT TRUE     AS test2
      ,coalesce(stringexpression, '') = ''      AS test_coalesce1
      ,coalesce(stringexpression, '  ') = '  '  AS test_coalesce2
      ,coalesce(stringexpression, '') = '  '    AS test_coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , (NULL)
   , ('   ')                -- not different from '' in char(n)
   ) sub(stringexpression);
 stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | t              | t
                  |             | t     | t     | t              | t              | t
                  | t           | t     | t     | t              | t              | t

textで "null or empty string"をテストします

SELECT stringexpression 
      ,stringexpression = ''                    AS simple_test
      ,(stringexpression = '')  IS NOT FALSE    AS test1
      ,(stringexpression <> '') IS NOT TRUE     AS test2
      ,coalesce(stringexpression, '') = ''      AS test_coalesce1
      ,coalesce(stringexpression, '  ') = '  '  AS test_coalesce2
      ,coalesce(stringexpression, '') = '  '    AS test_coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , (NULL)
   , ('   ')                -- different from '' in a sane character type like text
   ) sub(stringexpression);
 stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | f              | f
                  |             | t     | t     | t              | t              | f
                  | f           | f     | f     | f              | f              | f

dbfiddle here
旧SQLフィドル

関連する

217

Nullと空をチェックするには

coalesce(string, '') = ''

Null、空、スペースをチェックする(文字列を削除する)

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

空の末尾スペースがあるかもしれないなら、おそらくより良い解決策はありません。 COALESCEはあなたの問題のようなものです。

2
Świstak35

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

where length(stringexpression) > 0;
1
yglodt

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

PostgreSQLと同様にMS SQLでも試してみました。

1
TarasB

データベースに大量のレコードがある場合、null checkにはもっと時間がかかる可能性があります。1)where columnname is null 2)where not exists() 3)WHERE (case when columnname is null then true end)

0
Ambrish Rajput

NULL可能フィールドを比較するための私の好んだ方法は、NULLIF(nullablefield、:ParameterValue)IS NULL AND NULLIF(:ParameterValue、nullablefield)IS NULLです。これは面倒ですが、Coalesceが不可能な場合もある中で普遍的な用途です。

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

0
Danilo da Silva