Лучший способ проверить "пустое или нулевое значение"

Каков наилучший способ проверить, является ли значение пустой или пустой строкой в ​​операторах sql Postgres?

Значение может быть длинным выражением, поэтому предпочтительно, чтобы он записывался только один раз под контролем.

В настоящее время я использую:

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

Но это выглядит немного уродливо.

stringexpression может быть столбцом или выражением char(n), содержащим столбцы char(n) с конечными пробелами.

Каков наилучший способ?

Ответ 1

Выражение stringexpression = '' дает:

TRUE.. для '' (или для любой строки, состоящей только из пробелов с типом данных char(n))
NULL.. для NULL
FALSE.. для чего-нибудь еще

Итак, чтобы проверить: "stringexpression является либо NULL, либо пустым" :

(stringexpression = '') IS NOT FALSE

Или обратный подход (может быть проще читать):

(stringexpression <> '') IS NOT TRUE

Работает для любого типа символа, включая устаревший char(n), который вряд ли когда-либо будет полезен. Руководство по операторам сравнения.

Или используйте уже имеющееся выражение, просто без trim(), которое было бы бесполезно для char(n) (см. ниже), или оно будет включать строки, состоящие только из пробелов в тесте для другие типы символов:

coalesce(stringexpression, '') = ''

Но выражения наверху быстрее.

Утверждение противоположное: "stringexpression не является ни NULL, ни пустым" еще проще:

stringexpression <> ''

О char(n)

Не путайте этот тип данных с другими типами символов, например varchar(n), varchar, text или "char" (с кавычки), которые являются всеми полезными типами данных. Речь идет об устаревшем типе данных с очень ограниченной полезностью: char(n), сокращение для: character(n). Кроме того, char и character являются короткими для char(1)/character(1) (то же самое).

В char(n) (в отличие от других типов строк!) пустая строка не отличается от любой другой строки, состоящей только из пробелов. Все они складываются в n пробелов в char(n) за определение типа. Логически следует, что это работает и для char(n):

coalesce(stringexpression, '') = ''

Так же, как и эти (которые не будут работать для других типов символов):

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

Demo

Пустая строка равна любой строке пробелов при нажатии на 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):

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

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 здесь
Старый скрипт SQL

по теме:

Ответ 2

Чтобы проверить значение null и empty:

coalesce(string, '') = ''

Проверить нулевые, пустые и пробелы (обрезать строку)

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

Ответ 3

Если могут быть пустые конечные пробелы, возможно, нет лучшего решения. COALESCE предназначен только для таких проблем, как ваш.

Ответ 4

Я видел, что люди используют stringexpression > ''. Это может быть не самым быстрым, но бывает одним из самых коротких.

Пробовал это на MS SQL, а также на PostgreSQL.

Ответ 5

Мой предпочтительный способ сравнения полей с нулевым значением: NULLIF (nullablefield,: ParameterValue) IS NULL AND NULLIF (: ParameterValue, nullablefield) IS NULL. Это громоздко, но имеет универсальное применение, в то время как Coalesce в некоторых случаях невозможно.

Второе и обратное использование NULLIF связано с тем, что "NULLIF (nullablefield,: ParameterValue) IS NULL" всегда возвращает "true", если первый параметр имеет значение null.

Ответ 6

Если база данных с большим количеством записей, тогда null check может занять больше времени вы можете использовать проверку нуля различными способами, например: 1) where columnname is null 2) where not exists() 3) WHERE (case when columnname is null then true end)

Ответ 7

Проверка длины строки также работает и является компактной:

where length(stringexpression) > 0;