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

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

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

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

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

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

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

Какой способ лучше?

12 ответов

Решение

Выражение 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 не является ни пустым, ни пустым " еще проще:

stringexpression <> ''

Около char(n)

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

В char(n) (в отличие от других типов строк!) пустая строка не отличается от любой другой строки, состоящей только из пробелов. Все они складываются в п пространства в char(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):

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 скрипка

Связанные с:

Чтобы проверить на пустое и пустое:

coalesce(string, '') = ''

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

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

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

where length(stringexpression) > 0;

Многие ответы являются кратчайшим путем, но не обязательно лучшим, если в столбце много нулей. Прерывание проверок позволяет оптимизатору быстрее оценить проверку, так как ему не нужно работать над другим условием.

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

Сравнение строк не требует оценки, поскольку первое условие ложно.

Другой способ

nullif(trim(stringExpression),'') is not null

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

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

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

Я столкнулся с подобным случаем, если бы мне пришлось это сделать. Определение моей таблицы выглядит так:

id(bigint)|name (character varying)|results(character varying)
1 | "Peters"| [{"jk1":"jv1"},{"jk1":"jv2"}]
2 | "Russel"| null

Чтобы отфильтровать столбец результатов с нулевым или пустым в нем, сработало следующее:

SELECT * FROM tablename where results NOT IN  ('null','{}'); 

Это вернуло все строки, которые не являются нулевыми в результатах.

Я не уверен, как исправить этот запрос, чтобы он возвращал все строки, которые не равны нулю в результатах.

SELECT * FROM tablename where results is not null; 

--- хм, что мне не хватает, кастинг? любые входы?

found this post looking for a solution to 'don't show me data that is '' (blank or single space char) or null'. in my case, we only want to show the user records with these values populated. i hope this response helps another looking for the same. the answers above didn't work in my case.

our app is running rails with postgres. looking at how rails builds the query for .where.not(company_website: [nil, '']) in our app, which works just fine, i can see the resulting sql statement in console.

WHERE NOT ((contacts.company_website = '' OR contacts.company_website IS NULL))

i added this bit and it works as intended.

Мне нравится ответ иглодта, но расчет точной длины может быть дорогостоящим для больших наборов и больших струн, поэтому я использую:

      coalesce(trim('a') > '','f')

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

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

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

Другие вопросы по тегам