С удивлением обнаружил, что в запросах NULL не равен NULL

1. newborn 29.09.16 10:22 Сейчас в теме
В двух временных таблицах в поле появлялось NULL. А в результирующей таблице по этому полю шло левое соединение. И получалось, что связи по этому полю нет.
Выяснилось, что NULL <> NULL.
Это только я об этом не знал?
Просто подумал, что возможно знание этого факта кому-нибудь будет полезно.
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. Boneman 297 29.09.16 10:25 Сейчас в теме
(1) newborn, никогда не пробовал соединять и сравнивать NULL-ы )))) Но так-то, вроде логично ))) ка кожно сравнивать, то чего нет ))))
4. herfis 491 29.09.16 10:29 Сейчас в теме
(1) newborn, Да. Концепция отсутствия значения, которое не может быть равно самому себе - кроме SQL есть и в других языках программирования.
Только учти, что при анализе выборки результата запроса в языке 1С null = null :)
16. Onwardv 62 29.09.16 12:42 Сейчас в теме
(1) newborn,
Это не новость, в описание 1с есть. Мол, любое сравнение на NULL вернет ЛОЖЬ
Для соединения используйте вариант:
ВЫБРАТЬ ВТ_Первая.Поле1,
    ВТ_Вторая.Поле1
ИЗ ВТ_Первая как ВТ_Первая
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Вторая КАК ВТ_Вторая
ПО ВТ_Первая.ПолеБезNULL=ВТ_Вторая.ПолеБезNULL
    И (ВТ_Первая.ПолеNULL ЕСТЬ NULL)
    И (ВТ_Вторая.ПолеNULL ЕСТЬ NULL)

Обратите внимание, что при отсутствие условия соединения значимых полей, т.е., в примере, без первого условия "ВТ_Первая.ПолеБезNULL=ВТ_Вторая.ПолеБезNULL", запрос вернет на каждое NULL из ВТ_Первая все записи из ВТ_Вторая, где ВТ_Вторая.ПолеNULL ЕСТЬ NULL.Произвойдет некое "умножение", если в обоих таблицах по 100 строк со значением NULL, то запрос вернет 10 000 строк
jobkostya1c_ERP; +1 Ответить
28. newborn 29.09.16 20:41 Сейчас в теме
(16) Onwardv,
Нет, я вышел из положения, приводя значение к пустой ссылке справочника
31. jobkostya1c_ERP 100 02.10.23 10:05 Сейчас в теме
(16)
с этими NULL всегда ставлю функции проверки ISNULL(<ЧтоТо>, 0) и с этим сравниваю. А вот теперь пошли "тяжелые задачи".
Ваш тест смотрю:
ВЫБРАТЬ
	1 КАК Поле1,
	2 КАК ПолеБезNULL,
	NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_Первая
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	3 КАК Поле1,
	2 КАК ПолеБезNULL,
	NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_ВТОРАЯ
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Первая.Поле1 КАК Поле1,
	ВТ_Вторая.Поле1 КАК Поле11
ИЗ
	ВТ_Первая КАК ВТ_Первая
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ВТОРАЯ КАК ВТ_Вторая
		ПО ВТ_Первая.ПолеБезNULL = ВТ_Вторая.ПолеБезNULL
			И (ВТ_Первая.ПолеNULL ЕСТЬ NULL)
			И (ВТ_Вторая.ПолеNULL ЕСТЬ NULL)
Показать


Выдает:
Прикрепленные файлы:
32. jobkostya1c_ERP 100 02.10.23 10:12 Сейчас в теме
(16) А так, умножение верно:

Код
ВЫБРАТЬ
   1 КАК Поле1,
   2 КАК ПолеБезNULL,
   NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_Первая

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   10,
   20,
   NULL
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   3 КАК Поле1,
   2 КАК ПолеБезNULL,
   NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_ВТОРАЯ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   11,
   22,
   NULL
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ВТ_Первая.Поле1 КАК Поле1,
   ВТ_Вторая.Поле1 КАК Поле11
ИЗ
   ВТ_Первая КАК ВТ_Первая
      ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ВТОРАЯ КАК ВТ_Вторая
      ПО (ВТ_Первая.ПолеNULL ЕСТЬ NULL)
         И (ВТ_Вторая.ПолеNULL ЕСТЬ NULL) 
Показать полностью
Прикрепленные файлы:
33. jobkostya1c_ERP 100 02.10.23 10:27 Сейчас в теме
(16) Речь, если сравнивать поле первой таблицы где одни NULL с полем другой таблицей где тоже есть NULL на равенство. И в запросе NULL <> NULL и будет ЛОЖЬ по соединению и получим при левом соединении отстуствие соединения таблиц (поле11 из второй таблицы где NULL).

Это если где-то NULL затесался в промежуточной таблице сложного запроса как реквизит через точку из пустой ссылки?

ВЫБРАТЬ
	1 КАК Поле1,
	2 КАК ПолеБезNULL,
	NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_Первая

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	10,
	20,
	NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	3 КАК Поле1,
	2 КАК ПолеБезNULL,
	NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_ВТОРАЯ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	11,
	22,
	NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Первая.Поле1 КАК Поле1,
	ВТ_Вторая.Поле1 КАК Поле11
ИЗ
	ВТ_Первая КАК ВТ_Первая
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ВТОРАЯ КАК ВТ_Вторая
		ПО ВТ_Первая.ПолеNULL = ВТ_Вторая.ПолеNULL
		
		  //(ВТ_Первая.ПолеNULL ЕСТЬ NULL)
		  //	И (ВТ_Вторая.ПолеNULL ЕСТЬ NULL)
Показать


Вот что будет:


А при таком условии
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ВТОРАЯ КАК ВТ_Вторая
		ПО ISNULL(ВТ_Первая.ПолеNULL, 9999) = ISNULL(ВТ_Вторая.ПолеNULL, 9999)

все будет сравниваться, а без функции нет?


Мы получим верный результат, т.к. будут сравниваться 9999 и 9999 (главное уникальный признак поставить чтоб не было в полях сравниваемых таблиц иначе получим дубли.
А если таблицы тяжелые что делать? Как удобнее фильтровать? В промежуточных таблицах на условия типа "ГДЕ НЕ ВТ_Первая.ПолеNULL ЕСТЬ NULL" с выгрузкой в промежуточную таблицу? Или кодом прогонять таблицу значений, опять в запрос?
3. DenisCh 29.09.16 10:28 Сейчас в теме
NULL не равен ничему.
Это азы NULL-операций в СУБДах.
morin; jobkostya1c_ERP; +2 Ответить
5. Voffka 29.09.16 10:29 Сейчас в теме
Может использовать что нить типо ЕстьNULL()?
aka Любитель XML; ipoloskov; alex-l19041; +3 Ответить
25. newborn 29.09.16 20:36 Сейчас в теме
(5) Voffka,
Да, я так собственно и вышел из положения.
В качестве оправдания могу сказать, что запрос был не мой. Хотя, это меня никак не характеризует, ибо я тоже вполне мог написать такой запрос. Там проблема была неочевидна...
6. herfis 491 29.09.16 10:36 Сейчас в теме
Точнее так - в SQL отсутствие значения является неопределенностью, которая не может быть равна ничему, в том числе и самой себе - настолько она неопределена :)
А в языках программирования бывает понятие математической неопределенности NaN, обладающее теми же свойствами.
7. Voffka 29.09.16 10:46 Сейчас в теме
Значение NULL не может быть сравнимо со значением NULL, мы не знаем, что именно сравнивать. Т.е. оба этих сравнения: NULL = NULL, NULL<>NULL - это не Истина или не Ложь, это неизвестно.
26. newborn 29.09.16 20:37 Сейчас в теме
(7) Voffka,
Запрос даёт чёткое значение ЛОЖЬ. Я проверял.
8. ipoloskov 161 29.09.16 11:07 Сейчас в теме
Таки да.
В условиях используйте конструкцию ЕстьNULL(СвязаннаяТаблица.ЛюбоеПоле, 0) = 0
jobkostya1c_ERP; +1 Ответить
9. Voffka 29.09.16 11:08 Сейчас в теме
А вдруг вот это тоже удивит: :)
Если в запросе есть необходимость проанализировать значение некоторого выражения на равенство NULL, следует использовать не операции сравнения (=, <>), а специальный оператор проверки значения выражения на равенство NULL, имеющий следующий синтаксис:

<Выражение> ЕСТЬ [НЕ] NULL
27. newborn 29.09.16 20:39 Сейчас в теме
(9) Voffka,
Нет, я встретился с другой проблемой. У меня в запросе было левое соединение по полю, которое в обеих соединяемых таблицах было NULL. Я смотрю в регистр, в списке записей, вижу очевидное совпадение, а потом выполняю запрос - а связи нет.
Не сразу догадался, в чём проблема.
jobkostya1c_ERP; +1 Ответить
10. mazechild 29.09.16 11:56 Сейчас в теме
Здесь вообще кто-нибудь пробовал изучать СКД? Программирование?
11. DenisCh 29.09.16 11:58 Сейчас в теме
(10) mazechild, Нет. Ты единственный уникальный человек в этом роде.
17. mazechild 29.09.16 12:58 Сейчас в теме
(11) DenisCh, (12) Boneman, Шутки за 200?
18. DenisCh 29.09.16 13:02 Сейчас в теме
(17) mazechild, да. Номер счёта выслать?
12. Boneman 297 29.09.16 12:07 Сейчас в теме
(10) mazechild, а что такое СКД ?))))
14. DenisCh 29.09.16 12:12 Сейчас в теме
(12) Boneman, Снайперский Карабин Дегтярёва.
jif; Boneman; +2 Ответить
13. fromtomike 49 29.09.16 12:12 Сейчас в теме
С удивлением обнаружил, что запрос типа:

	Запрос = Новый Запрос(
	"ВЫБРАТЬ
	|	Контрагенты.Ссылка
	|ИЗ
	|	Справочник.Контрагенты КАК Контрагенты
	|ГДЕ
	|	Контрагенты.Ссылка В ИЕРАРХИИ(&КорневаяГруппа)"
	);
	Запрос.УстановитьПараметр("КорневаяГруппа", Справочники.Контрагенты.ПустаяСсылка());

Показать


Вернет все элементы справочника
15. herfis 491 29.09.16 12:20 Сейчас в теме
А еще, а еще!
Еще в 1С NULL в некоторых случаях физически содержится в полях данных.
Например, NULL записывается в те реквизиты элементов справочников, для которых в конфигураторе указано, что они доступны только для группы. И еще где-то, но я уже забыл :)
19. vadim1011985 97 29.09.16 13:11 Сейчас в теме
Если уж пошли такие открытиях- то сам недавно обнаружил следующее (Это касается СКД)

Если в наборе данных использовать временные таблицы например одну по документам а одну виртуальной таблице регистра хозрасченый (например ХозрасчетныйОборотыДтКт)

И в таблице по документам использовать параметры &НачалоПериода, &КонецПериода а в таблице ХозрасчетныйОборотыДтКт в периодах использовать другие параметры для\ задания периода например
&НачалоПериодаДействи и &КонецПериодаДействия - то эти параметры будут игнорироваться системой и вместо них будет использоваться парfметры &НачалоПериода и &КонецПериода.

Я конечно понимаю что система сама создает для виртуальной таблицы хоз.расчетного регистра эти параметры (т.е. явно их можно не указывать) , но что бы так игнорировать указанные - для меня это было открытие
jobkostya1c_ERP; newborn; +2 Ответить
20. necropunk 9 29.09.16 13:35 Сейчас в теме
(19) vadim1011985, я когда-то, лет 5-7 назад, на поиск этого глюка почти 3 дня угробил. Там огромный отчет был... Ох, как я был зол...
21. vadim1011985 97 29.09.16 13:37 Сейчас в теме
(20) necropunk, мне повезло больше - часа 3 отлавливал. Удивительно что они его еще не исправили за столь длительный срок.
22. caponid 29.09.16 15:02 Сейчас в теме
(19) надо для параметров &НачалоПериодаДействи и &КонецПериодаДействия использование установить в "Всегда"
23. vadim1011985 97 29.09.16 16:53 Сейчас в теме
(22) caponid, А почему без этой галочки не работает ?
24. herfis 491 29.09.16 17:46 Сейчас в теме
Правильнее не "использовать всегда", а оформить кастомные параметры периодов виртуальных таблиц именно как параметры СКД - фигурными скобками. Тогда СКД не будет при автозаполнении фантазировать дефолтными параметрами СКД периодов виртуальных таблиц.
jobkostya1c_ERP; necropunk; +2 Ответить
29. docerman 69 29.09.16 20:57 Сейчас в теме
А вот еще у пустой ссылки в запросе реквизиты is null, а в объектной модели если реквизит ссылка то будет пустая ссылка, если число - то 0 и т.д., А еще для отладки формы в конфигураторе нужно Ctr + R нажать. А еще ...)
30. smaharbA 29.09.16 22:02 Сейчас в теме
С удивлением обнаружил, что уже двадцать - тридцать лет лезут долботятлы в мою богодельню
34. jobkostya1c_ERP 100 02.10.23 10:32 Сейчас в теме
Проверяю тесты:
Первый:
ВЫБРАТЬ
	1 КАК Поле1,
	2 КАК ПолеБезNULL,
	NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_Первая

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	10,
	20,
	NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	3 КАК Поле1,
	2 КАК ПолеБезNULL,
	NULL КАК ПолеNULL
ПОМЕСТИТЬ ВТ_ВТОРАЯ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	11,
	22,
	NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Первая.Поле1 КАК Поле1,
	ВТ_Вторая.Поле1 КАК Поле11
ИЗ
	ВТ_Первая КАК ВТ_Первая
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ВТОРАЯ КАК ВТ_Вторая
		ПО  (ВТ_Первая.ПолеNULL = ВТ_Вторая.ПолеNULL)		
		  И (ВТ_Первая.ПолеNULL ЕСТЬ NULL)
		  	И (ВТ_Вторая.ПолеNULL ЕСТЬ NULL)
Показать


Вернет пустую таблицу:
Прикрепленные файлы:
36. PlatonStepan 38 02.10.23 10:47 Сейчас в теме
проспись уже XD,
конечно будет пусто, если с NULL сравнивать: (ВТ_Первая.ПолеNULL = ВТ_Вторая.ПолеNULL)
35. succub1_5 88 02.10.23 10:36 Сейчас в теме
Ликбез (копипаста)
NULL - это специальное значение, которое используется в SQL для обозначения отсутствия данных. Оно отличается от пустой строки или нулевого значения, так как NULL означает отсутствие какого-либо значения в ячейке таблицы.

История появления NULL в SQL довольно интересна и длинна. В начале 1970-х годов Д. Камерер (D. Chamberlin) и Р. Бойд (R. Boyce) предложили использовать реляционную модель для полной замены иерархических и сетевых моделей данных, которые были актуальны в то время. Полная замена предполагала возможность хранения значений NULL в таблицах структуры базы данных.

Первоначально, NULL был создан как интегральный элемент реляционной модели данных. Это означало, что NULL мог быть использован в качестве значения для любого типа данных (целого числа, строки и т.д.) или даже целой строки (например, таких значений как "неизвестно" или "нет данных").

Когда была разработана SQL, NULL был реализован как специальное значение или маркер, который указывает на отсутствие значения в столбце. Таким образом, в SQL NULL означает отсутствие значения или неопределенное значение.

Однако, NULL создал некоторые проблемы при работе с данными в SQL. Например, если вы выполняете операцию на столбце, содержащем NULL значение, результат операции также будет NULL. Это означает, что использование NULL может приводить к нежелательным результатам, таким как непредсказуемое поведение.

Однако, важно понимать, что NULL не обязательно означает отсутствие информации или отсутствие значения в столбце. NULL может быть использован для разных целей, таких как указание на неопределенный результат для вычислений или как маркер для отметки отсутствия значения в таблице.
Оставьте свое сообщение
Вакансии
Программист
Санкт-Петербург
зарплата от 180 000 руб. до 240 000 руб.
Полный день

Разработчик 1С
Москва
зарплата от 150 000 руб. до 250 000 руб.
Полный день

Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Программист 1С
Екатеринбург
зарплата от 130 000 руб. до 170 000 руб.
Полный день

Программист 1C
Санкт-Петербург
зарплата от 140 000 руб. до 200 000 руб.
Полный день