Сегодня поговорим о
NULL. Почему стандарты разработки 1С обращают внимание на его обработку? Вот один вполне практический пример.Допустим, у нас есть отчёт. Строки сортируются по колонке с датой, а от порядка вывода зависит дальнейшая обработка или интерпретация результата.
И вот в этой колонке появляется
NULL — например, после левого соединения. А обработать его мы забыли.«Ничего страшного, при сортировке по возрастанию он всегда будет сверху», — думаем мы, привыкнув к MS SQL Server.
А вот и нет.
Отчёт годами работал на MS SQL Server. Перешли на PostgreSQL — и логика сломалась.
Нет, запрос не выдаёт ошибку. Нет, отчёт не стал тормозить. Он просто возвращает строки в другом порядке.
Причина — разные правила расположения
NULL при сортировке по умолчанию:🔹 MS SQL Server: при сортировке по возрастанию
NULL идёт в начале. 🔹 PostgreSQL: при той же сортировке
NULL оказывается в конце.При сортировке по убыванию — наоборот.[1][2]
На скриншоте как раз видно разницу: слева, в MS SQL, строка с
NULL находится над датами. Справа, в PostgreSQL, — под ними.Если алгоритм выбирает первую строку, обрабатывает записи последовательно или опирается на их положение, это уже не косметическое отличие.
В моём случае проблему решила явная замена
NULL на пустую дату.В запросе 1С выражение для ключа сортировки выглядит так:
ЕСТЬNULL(Данные.Дата, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаСортировкиДальше сортируем именно по этому полю:
УПОРЯДОЧИТЬ ПО ДатаСортировки ВОЗР
Теперь вместо
NULL в ключе сортировки используется конкретная дата. Разница в правилах расположения NULL больше не влияет на результат.[3][4]Но замена должна соответствовать задаче: здесь нам нужно, чтобы строки без даты шли первыми. Если они должны быть последними, правило сортировки нужно задать иначе.
И ещё нюанс: одинаковые даты не задают порядок строк между собой. Если он важен, нужны дополнительные поля сортировки.
"Потому что стандарт SQL не фиксирует положение NULL в ORDER BY — это оставлено на усмотрение разработчика СУБД. Причина в самой природе NULL.
1.NULL — это не значение, а маркер «неизвестно/отсутствует». Сравнение NULL = NULL даёт не ИСТИНА, а UNKNOWN (трёхзначная логика). Раз NULL не «равен» даже самому себе, он не встраивается в обычный линейный порядок — и каждая СУБД решает, куда его поместить.
2. Разработчики выбрали разные соглашения:
_____________________________________________________
СУБД | Где NULL по умолчанию
_____________________________________________________
PostgreSQL, Oracle | «больше» любого значения
SQL Server, MySQL/MariaDB | «меньше» любого значения
SQLite | как SQL Server
_____________________________________________________
Обратите внимание: Oracle/PostgreSQL исторически трактуют NULL как максимальное значение, а Microsoft/MySQL — как минимальное. Это унаследованные проектные решения, а не требование стандарта.
3. Явное управление. В СУБД, где это поддерживается, порядок задаётся ключевыми словами NULLS FIRST / NULLS LAST (PostgreSQL, Oracle), либо заменой значения функцией COALESCE/ISNULL/NVL в выражении сортировки.
Практический вывод для 1С: язык запросов транслируется в SQL конкретной СУБД, а позиция NULL в ORDER BY может отличаться на MS SQL и PostgreSQL. Чтобы сортировка была предсказуемой, NULL-значения лучше приводить явно — через ЕСТЬNULL(Поле, <значение>) в поле сортировки, а не полагаться на поведение конкретной СУБД."💯Поэтому рекомендация учитывать
NULL при упорядочивании — не формальность. Стандарт 1С отдельно предупреждает о различиях между СУБД.‼️При миграции проверяйте не только ошибки и производительность, но и корректность результатов. Быстро работающий отчёт ещё не означает правильно работающий отчёт.
❓А вам встречались такие «тихие» изменения после перехода на другую СУБД?
