Значение 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 Сотрудники