Значение NULL в SQL – неизвестное значение

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

Если рассмотреть диаграмму таблицы сотрудников учебной БД, то можно заметить, что последний столбец диаграммы указывает возможность наличия неизвестных значение в конкретном поле, а именно:

  • Отчество. Вполне возможно, что сотрудником является гражданин страны, где не используется отчество.
  • Дата увольнения может отсутствовать, так как увольнения еще не было.
  • Группа может быть неизвестна, потому что сотрудник может быть не распределен в группу на каком-то из этапов приема на работу.
Диаграмма таблицы Сотрудники

Важно понять, что неизвестные (отсутствующие) значения – это не ноль (для числовых полей) и не пустая строка (для текстовых полей). Так как ноль является вполне конкретным значением, например, 0 рублей задолженности, а пустая строка сообщает о том, что на данный момент ничего кроме строки нулевой длины в поле строки быть не должно. В примере с отчеством, приведенном выше, вместо значения NULL можно задать пустую строку и это внесло бы дополнительную ясность, что отчество сотрудника нет в принципе, а не то, что его забыли внести.

Поиск отсутствующих значений

Выше было определено, что NULL не является конкретным значением, поэтому нужно понять, как операторы сравнения с ним будут работать. Никакое значение не может быть равно (также быть больше или меньше) неизвестному значению, даже условие NULL = NULL является ложным. Чтобы определить отсутствующее значения используется специальное условие IS NULL (является неизвестным). И наоборот, если требуется найти известные значения, то задается условие IS NOT NULL.

Рассмотрим задачу.
Найти всех сотрудников, которые были когда-либо уволены.

Решение.
Если в поле «Дата_увольнения» таблицы сотрудников отсутствует значение, то сотрудники работают на данный момент. Следовательно, нужно найти строки, где значение известно. Следующий sql-запрос выведет 7 строк, удовлетворяющих решению:

USE CallCenter

SELECT *
FROM Сотрудники
WHERE Дата_увольнения IS NOT NULL

Решим еще одну задачу.
Вывести непринятые звонки за 1 декабря 2014 года.

Решение.
Звонок считается непринятым, если в таблице «Звонки» в поле «Сотрудник» отсутствует id принявшего звонок оператора. Отфильтровав таблицу по полям «Сотрудник» и «Дата_Время», получим 184 строки, удовлетворяющих запросу:

USE CallCenter

SELECT *
FROM Звонки
WHERE Сотрудник IS NULL AND Дата_Время >= '01/12/2014 00:00:00' AND Дата_Время < '02/12/2014 00:00:00'

Обработка неизвестных значений

Если в своих запросах, Вы будете использовать поля, которые допускают значения NULL, то обязательно обрабатывайте такие поля, чтобы избежать ошибок. Например, любые арифметические операции или объединения строк, где в качестве аргумента будет хотя бы одно значение NULL, вернут неизвестное значение.

Рассмотрим пример.
Необходимо определить стаж работы каждого сотрудника, включая уволенных, на текущий момент. Стаж вывести в днях.

Для определения стажа необходимо найти интервал (разницу) между датой найма сотрудника и датой увольнения. Для этого можно использовать функцию DATEDIFF (ее описание можно найти в документации Microsoft). Но как быть с не уволенными сотрудниками, у которых отсутствует значение даты увольнения? Если выполнить ниже приведенный запрос, то можно убедиться, что большинство строк не покажут стаж:

USE CallCenter

SELECT id, DATEDIFF(DAY, Дата_найма, Дата_увольнения) AS Стаж
FROM Сотрудники

Поэтому обработаем поле «Дата_увольнения», применив функции ISNULL (если первый аргумент является NULL, то функция возвращает второй аргумент) и GETDATE (возвращает текущую системную дату и время). Следующий запрос выведет стаж в каждой строке:

USE CallCenter

SELECT id, DATEDIFF(DAY, Дата_найма, ISNULL(Дата_увольнения, GETDATE())) AS Стаж
FROM Сотрудники

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