Лучший способ проверить "пустое или нулевое значение"
Каков наилучший способ проверить, является ли значение пустым или пустым в выражениях 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) != '')
Сравнение строк не требует оценки, поскольку первое условие ложно.
Если могут быть пустые конечные пробелы, возможно, нет лучшего решения. 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 null
2) where not exists()
3) WHERE (case when columnname is null then true end)