Разное

Есть не null или не есть null: : Методическая поддержка для разработчиков и администраторов 1С:Предприятия 8

Содержание

ЕСТЬNULL в запросе 1С 8.3

NULL – это не что иное, как отсутствие значения. Многие путают его со значением «0» типа число, пустой ссылкой на какой-либо объект или же с пустой строкой. Из-за этого заблуждения возникает много ошибок.

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

Язык запросов в 1С основан на SQL, который не позволяет проверять на значение NULL обычным равенством. Ниже описаны два способа проверки на NULL в 1С 8.3.

Функция ЕСТЬNULL()

Функция языка запросов 1С 8.3 ЕСТЬNULL() имеет два входных параметра:

  • проверяемое выражение;
  • выражение замены.

Наша команда предоставляет услуги по консультированию, настройке и внедрению 1С.

Связаться с нами можно по телефону +7 499 350 29 00.

Услуги и цены можно увидеть по ссылке.

Будем рады помочь Вам!

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

Ниже рассмотрен пример. В нем выбираются все номенклатурные позиции табличной части товара из документа «Поступление товаров и услуг». При помощи левого соединения каждой номенклатуре проставляется последняя цена из регистра сведений «Цены номенклатуры».

В данном случае может возникнуть такая ситуация, что для какой-либо позиции может просто не быть цены в регистре. В таком случае функция ЕСТЬNULL вернет нам привычный ноль. Если ей не воспользоваться, то при попытке произвести арифметические операции над полем «Цена» со значением NULL мы получим ошибку.

ВЫБРАТЬ
Товары.Номенклатура КАК Товар,
ЕСТЬNULL(Цены.Цена, 0) КАК АктуальнаяЦена
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ПО Товары.Номенклатура = Цены.Номенклатура
ГДЕ
Товары.Ссылка = &СсылкаНаДокумент

ЕСТЬ NULL в операторе ВЫБОР

Аналогом функции ЕСТЬNULL() является «ЕСТЬ NULL», которая используется в операторе ВЫБОР и проверяет, является ли значение NULL. «ЕСТЬ» в данном случае подразумевает равенство и запрос предыдущего примера будет выглядеть следующим образом:

ВЫБРАТЬ
Товары.Номенклатура КАК Товар,
ВЫБОР
КОГДА Цены.Цена ЕСТЬ NULL
ТОГДА 0
ИНАЧЕ Цены.Цена
КОНЕЦ КАК АктуальнаяЦена
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
ПО Товары.Номенклатура = Цены.Номенклатура
ГДЕ
Товары.Ссылка = &СсылкаНаДокумент

Отличия функции ЕСТЬNULL() от ЕСТЬ NULL

Как вы могли увидеть из предыдущих примеров, в обоих случаях запрос возвращает одни и те же данные. Функция ЕСТЬNULL() является сокращенным вариантом ВЫБОР КОГДА … ЕСТЬ NULL … КОНЕЦ, но она все же будет предпочтительнее по следующим причинам:

  1. Функция EСТЬNULL() оптимизирует запрос. Она считывается один раз, поэтому при проверке сложного выражения, запрос отработает быстрее.
  2. Функция EСТЬNULL() сокращает конструкцию, за счет чего запрос становится более читабельным.
  3. При выполнении функции EСТЬNULL() выражение замены приводится к типу проверяемого выражения для типов строковых типов (к длине строки) и числовых (к разрядности).

В чем разница между «is Not Null» и «Not Is Null»

нет никакой разницы.

мне кажется, что там может быть разница, когда дело доходит до производительности. Кто-нибудь хочет поподробнее?

все основные двигатели (то есть MySQL, SQL Server, Oracle и PostgreSQL) объединит эти предикаты на этапе разбора, составляя из них одинаковые планы.

обработка этих условий более сложна, чем простое применение операторов в том или ином порядке.

для например, в Oracle, an IS NOT NULL (или NOT IS NULL) условие подразумевает возможность использования индекса, поэтому такой запрос:

SELECT  column
FROM    mytable
WHERE   column IS NOT NULL

скорее всего, будет исполнен с index fast full scan, без дополнительных проверок, сделанных во время выполнения (начиная с NULL значения просто не попадут в индекс, поэтому нет смысла их проверять).

, даже если каждая запись должна быть проверена, порядок проверок определяется оптимизатором (и не по заказу предикатов и операторы появляются в WHERE предложения).

например, вот план Oracle запрос:

SQL> EXPLAIN PLAN FOR
  2  
  2  SELECT *
  3  FROM   t_test
  4  WHERE  NOT column IS NULL
  5  /

Explained

SQL> SELECT  *
  2  FROM    TABLE(DBMS_XPLAN.display())
  3  /

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 958699830
----------------------------------------------------------------------------
| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |        |    30 |  1260 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T_TEST |    30 |  1260 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("COLUMN" IS NOT NULL)

Как видите,filter был переведен внутренне в IS NOT NULL (где Oracle наряду с большинством комментаторов, кажется, считают более подходящей формой)

обновление:

как отметил Джонатан Леффлер, это разница при оценке кортежей (в отличие от одиночных столбцы.)

кортеж, состоящий из смешанных NULL и неNULL значения не являются ни NULL или NOT NULL.

на PostgreSQL (который поддерживает этот предикат против кортежей), оба эти выражения:

SELECT  (1, NULL) IS NULL
SELECT  (1, NULL) IS NOT NULL

значение равно false.

В чем разница между «Is Not Null» и «не есть Null» — sql

Здесь нет никакой разницы.

Мне кажется, что есть разница, когда речь заходит о производительности. Кто-нибудь хочет поподробнее рассказать об этом?

Все основные движки (то есть MySQL , SQL Server , Oracle и PostgreSQL ) будут объединять эти предикаты на стадии синтаксического анализа, составляя из них идентичные планы.

Обработка этих условий более сложна, чем простое применение операторов в том или ином порядке.

Например , в Oracle условие IS NOT NULL (или NOT IS NULL ) подразумевает возможность использования индекса, поэтому запрос, подобный этому:

SELECT  column
FROM    mytable
WHERE   column IS NOT NULL

скорее всего, он будет выполняться с параметром index fast full scan, без каких-либо дополнительных проверок во время выполнения (поскольку значения NULL просто не попадут в индекс, поэтому проверять их нет смысла).

Даже если каждая запись будет нуждаться в проверке, порядок проверок будет определен оптимизатором (а не порядком появления предикатов и операторов в предложении WHERE ).

Например, вот план для запроса Oracle :

SQL> EXPLAIN PLAN FOR
  2  
  2  SELECT *
  3  FROM   t_test
  4  WHERE  NOT column IS NULL
  5  /

Explained

SQL> SELECT  *
  2  FROM    TABLE(DBMS_XPLAN.display())
  3  /

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 958699830
----------------------------------------------------------------------------
| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |        |    30 |  1260 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T_TEST |    30 |  1260 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("COLUMN" IS NOT NULL)

Как вы можете видеть, filter был переведен внутренне в IS NOT NULL (который Oracle вместе с большинством комментаторов, похоже, считает более подходящей формой)

Обновление:

Как отметил Джонатан Леффлер, это различие при оценке кортежей (в отличие от одиночных столбцов).

Кортеж, состоящий из смешанных значений NULL и не-NULL , не является ни NULL , ни NOT NULL .

В PostgreSQL (который поддерживает этот предикат против кортежей) оба эти выражения:

SELECT  (1, NULL) IS NULL
SELECT  (1, NULL) IS NOT NULL

оценить значение false.

загадочное дело выражения null >= 0 / Блог компании RUVDS.com / Хабр

Однажды я собирал материалы чтобы устроить ликбез по JavaScript для пары коллег. Тогда я и наткнулся на довольно интересный пример, в котором рассматривалось сравнение значения null с нулём. Собственно говоря, вот этот пример:

null > 0; // false
null == 0; // false
null >= 0; // true

На первый взгляд — полная бессмыслица. Как некое значение может быть не больше, чем 0, не равно нулю, но при этом быть больше или равно нулю?

Хотя поначалу я оставил это без особого внимания, решив, что всё дело в том, что JavaScript — это JavaScript, со всеми его странностями, этот пример меня заинтриговал. Связано ли это с типом null и с тем, как он обрабатывается, или с тем, как выполняются операции сравнения значений?

В итоге я решил докопаться до сути происходящего и начал рыться в единственном источнике истины для JavaScript — в спецификации ECMA. Сегодня я хочу рассказать вам о том, в какую глубокую кроличью нору я в результате провалился.

Абстрактный алгоритм сравнения для отношений

Рассмотрим первое сравнение:

null > 0; // false

В соответствии со спецификацией, операторы сравнения > и <, для того, чтобы выяснить, истинно или ложно выражение, пропускают его через так называемый абстрактный алгоритм сравнения для отношений. Здесь и далее мы будем цитировать фрагменты спецификации по тексту перевода «Стандарт ECMA-262, 3я редакция» с ресурса javascript.ru:

Сравнение x < y, где x и y являются значениями, возвращает true, false или undefined (последнее означает, что хотя бы один из операндов равен NaN). Такое сравнение производится следующим образом:
1. Вызвать ToPrimitive(x, подсказка Number).
2. Вызвать ToPrimitive(y, подсказка Number).
3. Если Тип(Результата(1)) равен String и Тип(Результата(2)) равен String - переход на шаг 16. (Заметим, что этот шаг отличается от шага 7 в алгоритме для оператора сложения + тем, что в нём используется и вместо или.)
4. Вызвать ToNumber(Результат(1)).
5. Вызвать ToNumber(Результат(2)).
6. Если Результат(4) равен NaN - вернуть undefined.
7. Если Результат(5) равен NaN - вернуть undefined.
8. Если Результат(4) и Результат(5) являются одинаковыми числовыми значениями - вернуть false.
9. Если Результат(4) равен +0 и Результат(5) равен -0 - вернуть false.
10. Если Результат(4) равен -0 и Результат(5) равен +0 - вернуть false.
11. Если Результат(4) равен +∞, вернуть false.
12. Если Результат(5) равен +∞, вернуть true.
13. Если Результат(5) равен -∞, вернуть false.
14. Если Результат(4) равен -∞, вернуть true.
15. Если математическое значение Результата (4) меньше, чем математическое значение Результата(5) (заметим, что эти математические значения оба конечны и не равны нулю) - вернуть true. Иначе вернуть false.
16. Если Результат(2) является префиксом Результата(1), вернуть false. (Строковое значение p является префиксом строкового значения q, если q может быть результатом конкатенации p и некоторой другой строки r. Отметим, что каждая строка является своим префиксом, т.к. r может быть пустой строкой.)
17. Если Результат(1) является префиксом Результата(2), вернуть true.
18. Пусть k - наименьшее неотрицательное число такое, что символ на позиции k Результата(1) отличается от символа на позиции k Результата(2). (Такое k должно существовать, т.к. на данном шаге установлено, что ни одна из строк не является префиксом другой.)
19. Пусть m - целое, равное юникодному коду символа на позиции k строки Результат(1).
20. Пусть n - целое, равное юникодному коду символа на позиции k строки Результат(2).
21. Если m < n, вернуть true. Иначе вернуть false.

Пройдёмся по этому алгоритму с нашим выражением null > 0.

Шаги 1 и 2 предлагают нам вызвать оператор ToPrimitive() для значений null и 0 для того, чтобы привести эти значения к их элементарному типу (к такому, например, как Number или String). Вот как ToPrimitive преобразует различные значения:








Входной типРезультат
UndefinedПреобразование не производится
NullПреобразование не производится
BooleanПреобразование не производится
NumberПреобразование не производится
StringПреобразование не производится
ObjectВозвращает значение по умолчанию для объекта. Значение по умолчанию для объекта получается путём вызова для объекта внутреннего метода [[DefaultValue]] с передачей ему опциональной подсказки ПредпочтительныйТип.

В соответствии с таблицей, ни к левой части выражения, null, ни к правой части, 0, никаких преобразований не применяется.

Шаг 3 алгоритма в нашем случае неприменим, пропускаем его и идём дальше. На шагах 4 и 5 нам нужно преобразовать левую и правую части выражения к типу Number. Преобразование к типу Number выполняется в соответствии со следующей таблицей (здесь опущены правила преобразования для входных типов String и Object, так как они к теме нашего разговора отношения не имеют):







Входной типРезультат
UndefinedNaN
Null+0
BooleanРезультат равен 1, если аргумент равен true. Результат равен +0, если аргумент равен false.
NumberПреобразование не производится

В соответствии с таблицей, null будет преобразовано в +0, а 0 останется самим собой. Ни одно из этих значений не является NaN, поэтому шаги алгоритма 6 и 7 можно пропустить. А вот на шаге 8 нам надо остановиться. Значение +0 равно 0, в результате алгоритм возвращает false. Таким образом:

null > 0; // false
null < 0; // тоже false

Итак, почему null не больше и не меньше нуля мы выяснили. Теперь идём дальше — разберёмся с тем, почему null ещё и не равен нулю.

Абстрактный алгоритм сравнения для равенств

Рассмотрим теперь проверку на равенство null и 0:

null == 0; //false

Оператор == использует так называемый абстрактный алгоритм сравнения для равенств, возвращая в результате true или false. Вот этот алгоритм:

Сравнение x == y, где x и y являются значениями, возвращает true или false. Такое сравнение производится следующим образом:
1. Если Тип(x) отличается от Типа(y) - переход на шаг 14.
2. Если Тип(x) равен Undefined - вернуть true.
3. Если Тип(x) равен Null - вернуть true.
4. Если Тип(x) не равен Number - переход на шаг 11.
5. Если x является NaN - вернуть false.
6. Если y является NaN - вернуть false.
7. Если x является таким же числовым значением, что и y, - вернуть true.
8. Если x равен +0, а y равен -0, вернуть true.
9. Если x равен -0, а y равен +0, вернуть true.
10. Вернуть false.
11. Если Тип(x) равен String - вернуть true, если x и y являются в точности одинаковыми последовательностями символов (имеют одинаковую длину и одинаковые символы в соответствующих позициях). Иначе вернуть false.
12. Если Тип(x) равен Boolean, вернуть true, если x и y оба равны true или оба равны false. Иначе вернуть false.
13. Вернуть true, если x и y ссылаются на один и тот же объект или они ссылаются на объекты, которые были объединены вместе (см. раздел 13.1.2). Иначе вернуть false.
14. Если x равно null, а y равно undefined - вернуть true.
15. Если x равно undefined, а y равно null - вернуть true.
16. Если Тип(x) равен Number, а Тип(y) равен String, вернуть результат сравнения x == ToNumber(y).
17. Если Тип(x) равен String, а Тип(y) равен Number, вернуть результат сравнения ToNumber(x)== y.
18. Если Тип(x) равен Boolean, вернуть результат сравнения ToNumber(x)== y.
19. Если Тип(y) равен Boolean, вернуть результат сравнения x == ToNumber(y).
20. Если Тип(x) - String или Number, а Тип(y) - Object, вернуть результат сравнения x == ToPrimitive(y).
21. Если Тип(x) - Object, а Тип(y) - String или Number, вернуть результат сравнения ToPrimitive(x)== y.
22. Вернуть false.

Пытаясь понять, равно ли значение null значению 0, мы сразу переходим из шага 1 к шагу 14, так как Тип(x) отличается от Типа(y). Как ни странно, но шаги 14-21 тоже к нашему случаю не подходят, так как Тип(х) — это null. Наконец мы попадаем на шаг 22, после чего false возвращается как значение по умолчанию!
В результате и оказывается, что:

null == 0; //false

Теперь, когда ещё одна «тайна» JavaScript» раскрыта, разберёмся с оператором «больше или равно».

Оператор больше или равно (>=)

Выясним теперь, почему истинно такое выражение:

null >= 0; // true

Тут спецификация полностью выбила меня из колеи. Вот как, на очень высоком уровне, работает оператор >=:

Если null < 0 принимает значение false, то null >= 0 принимает значение true

В результате мы и получаем:

null >= 0; // true

И, на самом деле, в этом есть смысл. С точки зрения математики, если у нас есть два числа, x и y, и если x не меньше, чем y, тогда x должно быть больше чем y или равно ему.

Я предполагаю, что данный оператор работает именно так для того, чтобы оптимизировать вычисления. Зачем сначала проверять, больше ли x чем y, и, если это не так, проверять, равняется ли значение x значению y, если можно выполнить всего одно сравнение, проверить, меньше ли x чем y, а затем использовать результат этого сравнения для того, чтобы вывести результат исходного выражения.

Итоги

Вопрос о сравнении null и 0, на самом деле, не такой уж и сложный. Однако, поиск ответа открыл мне кое-что новое о JavaScript. Надеюсь, мой рассказ сделал то же самое для вас.

Уважаемые читатели! Знаете ли вы о каких-нибудь странностях JavaScript, которые, после чтения документации, уже перестают казаться таковыми?

0 или NULL? / Хабр

Есть три агрегатные функции, которые чаще всего используются на практике: COUNT, SUM и AVG.

И если первая уже обсуждалась ранее, то с остальными есть интересные нюансы с производительностью. Но давайте обо всем по порядку…

При использовании агрегатных функций на плане выполнения, в зависимости от входного потока, может встречаться два оператора: Stream Aggregate и Hash Match.

Для выполнения первого может требоваться предварительно отсортированный входной набор значений и при этом Stream Aggregate не блокирует выполнение последующих за ним операторов.

В свою очередь, Hash Match является блокирующим оператором (за редким исключением) и не требует сортировки входного потока. Для работы Hash Match используется хеш-таблица, которая создается в памяти и в случае неправильной оценки ожидаемого количества строк, оператор может сливать результаты в tempdb.


Итого получается, что Stream Aggregate хорошо работает на небольших отсортированных наборах данных, а Hash Match хорошо справляется с большими не отсортированными наборами и хорошо поддается параллельной обработке.

Теперь, когда мы преодолели теорию начнем смотреть как работают агрегатные функции.

Предположим, что нам нужно подсчитать среднюю цену среди всех продуктов:

SELECT AVG(Price) FROM dbo.Price

По таблице с достаточно простой структурой:

CREATE TABLE dbo.Price (
    ProductID INT PRIMARY KEY,
    LastUpdate DATE NOT NULL, 
    Price SMALLMONEY NULL,
    Qty INT
)

Поскольку у нас происходит скалярная агрегация, на плане выполнения мы ожидаемо увидим Stream Aggregate:

Внутри этот оператор выполняет две агрегирующие операции COUNT_BIG и SUM (хотя на физическом уровне выполняется это как одна операция) по столбцу Price:

Не забываем, что среднее вычисляется только для NOT NULL, поскольку операция COUNT_BIG идет по столбцу, а не со звездочкой. Соответственно, такой запрос:

SELECT AVG(v)
FROM (
    VALUES (3), (9), (NULL)
) t(v)

вернет в качестве результата не 4, а 6.

Теперь посмотрим на Compute Scalar, внутри которого есть интересное выражение для проверки деления на ноль:

Expr1003 =
    CASE WHEN [Expr1004]=(0)
        THEN NULL
        ELSE [Expr1005]/CONVERT_IMPLICIT(money,[Expr1004],0)
    END

Попробуем подсчитать общую сумму:

SELECT SUM(Price) FROM dbo.Price

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

Но если посмотреть на операции, которые выполняет Stream Aggregate

можно капельку удивиться. Зачем SQL Server подсчитывает количество, если мне нужна только сумма? Ответ кроется в Compute Scalar:

[Expr1003] = Scalar Operator(CASE WHEN [Expr1004]=(0) THEN NULL ELSE [Expr1005] END)

Если не брать во внимание COUNT, то согласно семантике языка T-SQL, когда нет строк во входном потоке, то мы должны возвращать NULL, а не 0. Такое поведение работает как для скалярной, так и для векторной агрегации:

SELECT LastUpdate, SUM(Price)
FROM dbo.Price
GROUP BY LastUpdate
OPTION(MAXDOP 1)
Expr1003 = Scalar Operator(CASE WHEN [Expr1008]=(0) THEN NULL ELSE [Expr1009] END)

Более того, такая проверка делается как для NULL, так и для NOT NULL столбцов. Теперь рассмотрим примеры в которых будут полезны описанные выше особенности SUM и AVG.

Если мы хотим посчитать среднее, то не нужно использовать COUNT + SUM:

SELECT SUM(Price) / COUNT(Price) FROM dbo.Price

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

Далее… Явно передавать NULL в агрегатную функцию нет необходимости:

SELECT
      SUM(CASE WHEN Price < 100 THEN Qty ELSE NULL END),
      SUM(CASE WHEN Price > 100 THEN Qty ELSE NULL END)
FROM dbo.Price

Поскольку в такой конструкции:

SELECT
      SUM(CASE WHEN Price < 100 THEN Qty END),
      SUM(CASE WHEN Price > 100 THEN Qty END)
FROM dbo.Price

Оптимизатор подстановку делает автоматически:

Но что, если я хочу получить 0 в результатах вместо NULL? Очень часто используют ELSE и не задумываются:

SELECT
      SUM(CASE WHEN Price < 100 THEN Qty ELSE 0 END),
      SUM(CASE WHEN Price > 100 THEN Qty ELSE 0 END)
FROM dbo.Price

Очевидно, что в таком случае мы достигнем желаемого… да и одно предупреждение перестанет мозолить глаза:

Warning: Null value is eliminated by an aggregate or other SET operation.

Хотя лучше всего писать запрос вот так:

SELECT
      ISNULL(SUM(CASE WHEN Price < 100 THEN Qty END), 0),
      ISNULL(SUM(CASE WHEN Price > 100 THEN Qty END), 0)
FROM dbo.Price

И это хорошо не потому, что оператор CASE станет работать быстрее. Мы то уже знаем, что оптимизатор туда подставляет ELSE NULL автоматом… Так в чем же преимущества последнего варианта?

Как оказалось, операции агрегирования, в которых преобладают NULL значения обрабатываются быстрее.

SET STATISTICS TIME ON

DECLARE @i INT = NULL

;WITH
    E1(N) AS (
        SELECT * FROM (
            VALUES
                (@i),(@i),(@i),(@i),(@i),
                (@i),(@i),(@i),(@i),(@i)
        ) t(N)
    ),
    E2(N) AS (SELECT @i FROM E1 a, E1 b),
    E4(N) AS (SELECT @i FROM E2 a, E2 b),
    E8(N) AS (SELECT @i FROM E4 a, E4 b)
SELECT SUM(N) -- 100.000.000
FROM E8
OPTION (MAXDOP 1)

Выполнение у меня заняло:

SQL Server Execution Times:
   CPU time = 5985 ms, elapsed time = 5989 ms.

Теперь меняем:

DECLARE @i INT = 0

И выполняем повторно:

SQL Server Execution Times:
   CPU time = 6437 ms, elapsed time = 6451 ms.

Не так существенно, но повод для оптимизации тем не менее это дает в определенных ситуациях.

Конец спектакля и занавес? Нет. Это еще не все…

Как говорил один мой знакомый: «Нет ни черного, ни белого… Мир многоцветен» и поэтому напоследок приведу интересный пример, когда NULL может вредить.

Создадим медленную функцию и тестовую таблицу:

USE tempdb
GO

IF OBJECT_ID('dbo.udf') IS NOT NULL
    DROP FUNCTION dbo.udf
GO

CREATE FUNCTION dbo.udf (@a INT)
RETURNS VARCHAR(MAX)
AS BEGIN
    DECLARE @i INT = 1000
    WHILE @i > 0 SET @i -= 1

    RETURN REPLICATE('A', @a)
END
GO

IF OBJECT_ID('tempdb.dbo.#temp') IS NOT NULL
    DROP TABLE #temp
GO

;WITH
    E1(N) AS (
        SELECT * FROM (
            VALUES
                (1),(1),(1),(1),(1),
                (1),(1),(1),(1),(1)
        ) t(N)
    ),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b),
    E4(N) AS (SELECT 1 FROM E2 a, E2 b)
SELECT *
INTO #temp
FROM E4

И выполним запрос:

SET STATISTICS TIME ON

SELECT SUM(LEN(dbo.udf(N)))
FROM #temp
SQL Server Execution Times:
   CPU time = 9109 ms, elapsed time = 11603 ms.

Теперь попробуем результат выражения, который передается в SUM, обернуть в ISNULL:

SELECT SUM(ISNULL(LEN(dbo.udf(N)), 0))
FROM #temp
SQL Server Execution Times:
   CPU time = 4562 ms, elapsed time = 5719 ms.

Скорость выполнения сократилась в 2 раза. Сразу скажу, что это не магия… А баг в движке SQL Server-а, который Microsoft уже «вроде как» исправила в SQL Server 2012 CTP.

Суть проблемы в следующем: результат выражения внутри функций SUM или AVG может выполняться дважды, если оптимизатор считает, что может вернуться NULL.

Все тестировалось на Microsoft SQL Server 2012 (SP3) (KB3072779) — 11.0.6020.0 (X64).

Если хотите поделиться этой статьей с англоязычной аудиторией:
What is faster inside SUM & AVG: 0 or NULL?

SQL: IS NOT NULL Условие


В этом руководстве по SQL объясняется, как использовать условие SQL IS NOT NULL с синтаксисом и примерами.

Описание

Условие IS NOT NULL используется в SQL для проверки ненулевого значения. Он возвращает TRUE, если найдено значение, отличное от NULL, в противном случае возвращает FALSE. Его можно использовать в операторах SELECT, INSERT, UPDATE или DELETE.

Синтаксис

Синтаксис условия IS NOT NULL в SQL:

 выражение НЕ ПУСТО 

Параметры или аргументы

выражение
Выражение, которое нужно проверить на наличие НЕ NULL значения.

DDL / DML для примеров

Если вы хотите следовать этому руководству, получите DDL для создания таблиц и DML для заполнения данных. Тогда попробуйте примеры в своей базе данных!

Получить DDL / DML

Пример — использование IS NOT NULL с оператором SELECT

При проверке значения, отличного от NULL, рекомендуется использовать оператор сравнения IS NOT NULL в SQL. Начнем с рассмотрения примера, показывающего, как использовать условие IS NOT NULL в операторе SELECT.

В этом примере у нас есть таблица с именем продуктов со следующими данными:

product_id название_продукта category_id
1 Груша 50
2 Банан 50
3 оранжевый 50
4 Яблоко 50
5 Хлеб 75
6 Ветчина нарезанная 25
7 Клинекс NULL

Введите следующий оператор SQL:

Попробуй это

 ВЫБРАТЬ *
ИЗ продуктов
ГДЕ category_id НЕ ПУСТО; 

Будет выбрано 6 записей.Вот результаты, которые вы должны увидеть:

product_id название_продукта category_id
1 Груша 50
2 Банан 50
3 оранжевый 50
4 Яблоко 50
5 Хлеб 75
6 Ветчина нарезанная 25

В этом примере будут возвращены все записи из таблицы products , где customer_id не содержит значения NULL.

Пример — использование IS NOT NULL с оператором UPDATE

Далее давайте рассмотрим пример использования условия IS NOT NULL в операторе UPDATE.

В этом примере у нас есть таблица с именем клиентов со следующими данными:

customer_id фамилия first_name избранное_вебсайт
4000 Джексон Джо techonthenet.com
5000 Смит Джейн digminecraft.com
6000 Фергюсон Саманта bigactivities.com
7000 Рейнольдс Аллен checkyourmath.com
8000 Андерсон Пейдж NULL
9000 Джонсон Дерек techonthenet.com

Введите следующий оператор UPDATE:

Попробуй это

 ОБНОВЛЕНИЕ клиентов
УСТАНОВИТЬ избранное_website = 'techonthenet.com'
ГДЕ favourite_website НЕ ПУСТО; 

Будет обновлено 5 записей. Снова выберите данные из таблицы клиентов :

 ВЫБРАТЬ * ИЗ клиентов; 

Вот результаты, которые вы должны увидеть:

customer_id фамилия first_name избранное_вебсайт
4000 Джексон Джо techonthenet.com
5000 Смит Джейн techonthenet.com
6000 Фергюсон Саманта techonthenet.com
7000 Рейнольдс Аллен techonthenet.com
8000 Андерсон Пейдж NULL
9000 Джонсон Дерек techonthenet.com

В этом примере все значения favourite_website в таблице customers будут обновлены до «techonthenet.com», где favourite_website содержит значение NULL. Как видите, favourite_website обновлен всего в одной строке.

Пример — использование IS NOT NULL с оператором DELETE

Далее давайте рассмотрим пример использования условия IS NULL в операторе DELETE.

В этом примере у нас есть таблица с именем заказов со следующими данными:

order_id customer_id дата заказа
1 7000 18.04.2016
2 5000 18.04.2016
3 8000 04.04.19
4 4000 20.04.2016
5 NULL 01.05.2016

Введите следующую инструкцию DELETE:

Попробуй это

 УДАЛИТЬ ИЗ заказов
ГДЕ customer_id НЕ ПУСТО; 

Будет удалено 4 записи.Снова выберите данные из таблицы заказов :

 ВЫБРАТЬ * ИЗ заказов; 

Вот результаты, которые вы должны увидеть:

order_id customer_id дата заказа
5 NULL 01.05.2016

В этом примере будут удалены все записи из таблицы orders , где customer_id не содержит значения NULL.

.

mysql — Разница между «IS NOT NULL» и «NOT (field = NULL)» в этих 2 запросах

Переполнение стека

  1. Около
  2. Продукты

  3. Для команд
  1. Переполнение стека
    Общественные вопросы и ответы

  2. Переполнение стека для команд
    Где разработчики и технологи делятся частными знаниями с коллегами

  3. Вакансии
    Программирование и связанные с ним технические возможности карьерного роста

  4. Талант
    Нанимайте технических специалистов и создавайте свой бренд работодателя

  5. Реклама
    Обратитесь к разработчикам и технологам со всего мира

  6. О компании

.

значений SQL NULL — ЕСТЬ NULL и НЕ NULL


Что такое значение NULL?

Поле со значением NULL — это поле без значения.

Если поле в таблице является необязательным, можно вставить новую запись или
обновить запись без добавления значения в это поле. Тогда поле будет
сохраняется со значением NULL.

Примечание: ПУСТОЕ значение отличается от нулевого значения или поля, которое
содержит пробелы. Поле со значением NULL — это поле, оставленное пустым.
при создании записи!


Как проверить значения NULL?

Невозможно проверить значения NULL с помощью операторов сравнения, таких как
=, <или <>.

Вместо этого нам придется использовать операторы IS NULL и IS NOT NULL.

IS NULL Синтаксис

ВЫБЕРИТЕ имена_столбцов
ИЗ имя_таблицы
ГДЕ имя_столбца ЕСТЬ NULL;

IS NOT NULL Синтаксис

ВЫБЕРИТЕ имена_столбцов
ИЗ имя_таблицы
ГДЕ имя_столбца НЕ ПУСТО;


Демо-база данных

Ниже представлен выбор из таблицы «Клиенты» в примере Northwind.
база данных:

Идентификатор клиента Имя клиента ContactName Адрес Город Почтовый индекс Страна
1 Альфредс Футтеркисте Мария Андерс Obere Str.57 Берлин 12209 Германия
2 Ana Trujillo Emparedados y helados Ана Трухильо Avda. de la Constitución 2222 México D.F. 05021 Мексика
3 Антонио Морено Такерия Антонио Морено Матадерос 2312 Мексика Д.F. 05023 Мексика
4 Вокруг Рога Томас Харди 120 Ганновер пл. Лондон WA1 1DP Великобритания
5 Berglunds snabbköp Кристина Берглунд Berguvsvägen 8 Лулео С-958 22 Швеция


Оператор IS NULL

Оператор IS NULL используется для проверки пустых значений (значений NULL).

В следующем SQL-запросе перечислены все клиенты со значением NULL в поле «Адрес»:

Пример

ВЫБЕРИТЕ CustomerName, ContactName, Address
FROM Customers
WHERE Address
НУЛЕВОЙ;

Попробуй сам »

Совет: Всегда используйте IS NULL для поиска значений NULL.


Оператор IS NOT NULL

Оператор IS NOT NULL используется для проверки непустых значений (NOT NULL
ценности).

Следующий SQL перечисляет всех клиентов со значением в поле «Адрес»:

Пример

ВЫБЕРИТЕ CustomerName, ContactName, Address
FROM Customers
WHERE Address
НЕ НУЛЬ;

Попробуй сам »


.

java — JPQL IS NOT NULL возвращает объекты с NULL

Переполнение стека

  1. Около
  2. Продукты

  3. Для команд
  1. Переполнение стека
    Общественные вопросы и ответы

  2. Переполнение стека для команд
    Где разработчики и технологи делятся частными знаниями с коллегами

  3. Вакансии
    Программирование и связанные с ним технические возможности карьерного роста

  4. Талант
    Нанимайте технических специалистов и создавайте свой бренд работодателя

  5. Реклама
    Обратитесь к разработчикам и технологам со всего мира

  6. О компании

Загрузка…

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *