Я заметил, что ряд запросов на работе и на SO используют ограничения в форме:
isnull(name,'') <> ''
Есть ли какая-то особая причина, почему люди делают это, а не более тонкие
name is not null
Это проблема устаревания или производительности?
Я заметил, что ряд запросов на работе и на SO используют ограничения в форме:
isnull(name,'') <> ''
Есть ли какая-то особая причина, почему люди делают это, а не более тонкие
name is not null
Это проблема устаревания или производительности?
where isnull(name,'') <> ''
эквивалентно
where name is not null and name <> ''
что, в свою очередь, эквивалентно
where name <> ''
(если имя IS NULL
, окончательное выражение будет оцениваться неизвестным и строка не возвращается)
Использование шаблона ISNULL
приведет к сканированию и будет менее эффективным, как видно из приведенного ниже теста.
SELECT ca.[name],
[number],
[type],
[low],
[high],
[status]
INTO TestTable
FROM [master].[dbo].[spt_values]
CROSS APPLY (SELECT [name]
UNION ALL
SELECT ''
UNION ALL
SELECT NULL) ca
CREATE NONCLUSTERED INDEX IX_TestTable ON dbo.TestTable(name)
GO
SELECT name FROM TestTable WHERE isnull(name,'') <> ''
SELECT name FROM TestTable WHERE name is not null and name <> ''
/*Can be simplified to just WHERE name <> '' */
Что должно дать вам план выполнения, который вам нужен.
is not null
Будет проверять, не поле не пустое. Если поле содержит пустую строку, то поле больше не равно null.
isnull(name, '') <> name
Проверяет как пустую, так и пустую строку.
isnull(name,'') <> :name
является сокращением для (name is null or name <> :name)
(предполагая, что :name
никогда не содержит пустую строку, поэтому почему подобные сокращения могут быть плохими).
По производительности, это зависит. Операторы or
в предложениях where
могут дать очень плохую производительность. Однако функции на столбцах ухудшают использование индекса. Как обычно: профиль.
isnull(name,'') <> name
Ну, я вижу, что они используют это, потому что этот путь, если имя не соответствует или равно null, возвращает его как неудачное сравнение. Это действительно означает: name is null
или name <> name
Где, как этот name is not null
, просто проверяет, имеет ли имя значение null.
Они не означают одно и то же.
name is not null
Это проверяет записи, где поле имени равно null
isnull(name,'') <> name
Это изменяет значение нулевых полей на пустую строку, чтобы их можно было использовать в сравнении. В SQL Server (но не в Oracle, я думаю), если значение равно null, и оно используется для сравнения эквалайзера или неравенства, это не будет считаться, потому что null означает, что я не знаю значения и, следовательно, не является фактическим значением. Поэтому, если вы хотите убедиться, что при сопоставлении учитываются нулевые записи, вам нужны ISNULL или COALESCE (который является термином ASCII STANDARD для использования в качестве ISNULL doen't во всех базах данных).
То, что вы должны смотреть, это differnece между
isnull(a.name,'') <> b.name
a.name < > b.name
тогда вы поймете, почему ISNULL необходим для получения правильных результатов.
Я, по-видимому, неправильно понял ваш вопрос. Поэтому позвольте мне нанести свой первый ответ и попробовать следующее:
isnull(name,'') <> ''
является ошибочным ярлыком для
name is not null and name <> ''
Другие указали на функциональную разницу. Что касается проблемы производительности, в Postgres я обнаружил, что - о, я должен упомянуть, что Postgres имеет функцию "coalesce", которая эквивалентна "isnull", найденной в некоторых других диалектах SQL, но в Postgres, говоря
where coalesce(foobar,'')=''
значительно быстрее, чем
where foobar is null or foobar=''
Кроме того, может быть намного быстрее сказать
where foobar>''
над
where foobar!=''
Больше, чем тест, может использовать индекс и, таким образом, пропускать все пробелы, в то время как тест не равный должен делать полный просмотр файла. (Предполагая, что у вас есть индекс в поле, и ни один другой индекс не используется в предпочтении.)
Также, если вы хотите использовать индекс в этом столбце, используйте
name is not null and name <> ''
Эти два запроса не совпадают. Например, у меня нет среднего имени, это известный факт, который можно сохранить как
MiddleName=''
Однако, если мы не знаем кого-то среднего имени, мы можем хранить NULL. Таким образом, ISNULL (MiddleName, '') означает "лица без известных средних имен".
Он должен обрабатывать как пустую строку, так и NULL
. Хотя хорошо иметь возможность иметь дело с одним утверждением, isnull
является проприетарным синтаксисом. Я бы написал это с помощью переносного стандартного SQL как
NULLIF(name, '') IS NOT NULL