isnull по сравнению с является пустым

Я заметил, что много запросов на работе и на ТАК используют ограничения в форме:

isnull(name,'') <> ''

Есть ли конкретная причина, почему люди делают это а не более краткое

name is not null

Действительно ли это - наследие или проблема производительности?

20
задан tgandrews 25 June 2010 в 14:49
поделиться

10 ответов

where isnull(name,'') <> ''

эквивалентно

where name is not null and name <> '' 

, что, в свою очередь, эквивалентно

where name <> ''

(если имя IS NULL , окончательное выражение будет оцениваться как unknown, а строка не будет возвращена)

Использование шаблона 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 <> '' */

Что должно дать вам план выполнения, который вам нужен.

enter image description here

37
ответ дан 29 November 2019 в 23:00
поделиться
is not null

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

isnull(name, '') <> name

Проверяет наличие как нулевой, так и пустой строки.

14
ответ дан 29 November 2019 в 23:00
поделиться
isnull(name,'') <> name

Я вижу, что они используют это, потому что таким образом, если имя не совпадает или равно null, оно возвращается как неудачное сравнение. На самом деле это означает: name is null или name <> name

Тогда как этот name is not null просто проверяет, не является ли имя нулевым.

1
ответ дан 29 November 2019 в 23:00
поделиться

Они означают не одно и то же.

name is not null 

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

isnull(name,'') <> name  

Это изменяет значение пустых полей на пустую строку, чтобы их можно было использовать при сравнении. В SQL Server (но не в Oracle, я думаю), если значение равно нулю и используется для сравнения равенства или неравенства, оно не будет рассматриваться, потому что null означает, что я не знаю значение и, следовательно, не является фактическим значением. Поэтому, если вы хотите убедиться, что при сравнении учитываются нулевые записи, вам понадобится ISNULL или COALESCE (это СТАНДАРТНЫЙ термин ASCII для использования, поскольку ISNULL не работает во всех базах данных).

Вам следует обратить внимание на разницу между

isnull(a.name,'') <> b.name  

a.name <> b.name

, тогда вы поймете, почему ISNULL необходим для получения правильных результатов.

1
ответ дан 29 November 2019 в 23:00
поделиться

Очевидно, я неправильно понял ваш вопрос. Итак, позвольте мне дать свой первый ответ и попробовать следующий:

isnull(name,'') <> ''

- это ошибочный ярлык для

name is not null and name <> ''
1
ответ дан 29 November 2019 в 23:00
поделиться

Он обрабатывает как пустую строку, так и NULL . Хотя хорошо иметь возможность работать с одним оператором, isnull является частным синтаксисом. Я бы написал это, используя переносимый стандартный SQL, как

NULLIF(name, '') IS NOT NULL
0
ответ дан 29 November 2019 в 23:00
поделиться

isnull (name, '') <>: name - это сокращение для (name is null или name <>: name) (при условии, что : name никогда не содержит пустой строки, поэтому такие сокращения могут быть плохими).

С точки зрения производительности, это зависит от обстоятельств. Операторы или в , где предложения могут дать крайне низкую производительность. Однако функции для столбцов ухудшают использование индекса. Как обычно: профиль.

2
ответ дан 29 November 2019 в 23:00
поделиться

Другие указали на функциональную разницу. Что касается проблемы с производительностью, то в Postgres я обнаружил, что - о, я должен упомянуть, что Postgres имеет функцию «coalesce», которая является эквивалентом «isnull», найденного в некоторых других диалектах SQL, но в Postgres, говоря

where coalesce(foobar,'')=''

значительно быстрее, чем

where foobar is null or foobar=''

Кроме того, может быть намного быстрее сказать

 where foobar>''

вместо

where foobar!=''

. Тест «больше, чем» может использовать индекс и, таким образом, пропускать все пробелы, в то время как тест с неравенством для полного чтения файла. (Предполагается, что у вас есть индекс для поля, и никакой другой индекс не используется в предпочтении.)

1
ответ дан 29 November 2019 в 23:00
поделиться

Также, если вы хотите использовать индекс в этом столбце, используйте

name is not null and name <> '' 
0
ответ дан 29 November 2019 в 23:00
поделиться

Эти два запроса не совпадают. Например, у меня нет второго имени, это известный факт, который можно сохранить как

MiddleName=''

. Однако, если мы не знаем чье-то отчество, мы можем сохранить NULL. Итак, ISNULL (отчество, '') означает «лица без известных отчества».

0
ответ дан 29 November 2019 в 23:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: