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

1. newborn 29.09.16 10:22 Сейчас в теме
В двух временных таблицах в поле появлялось NULL. А в результирующей таблице по этому полю шло левое соединение. И получалось, что связи по этому полю нет.
Выяснилось, что NULL <> NULL.
Это только я об этом не знал?
Просто подумал, что возможно знание этого факта кому-нибудь будет полезно.
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Boneman 298 29.09.16 10:25 Сейчас в теме
(1) newborn, никогда не пробовал соединять и сравнивать NULL-ы )))) Но так-то, вроде логично ))) ка кожно сравнивать, то чего нет ))))
4. herfis 500 29.09.16 10:29 Сейчас в теме
(1) newborn, Да. Концепция отсутствия значения, которое не может быть равно самому себе - кроме SQL есть и в других языках программирования.
Только учти, что при анализе выборки результата запроса в языке 1С null = null :)
16. Onwardv 65 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 500 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 163 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 298 29.09.16 12:07 Сейчас в теме
(10) mazechild, а что такое СКД ?))))
14. DenisCh 29.09.16 12:12 Сейчас в теме
(12) Boneman, Снайперский Карабин Дегтярёва.
jif; Boneman; +2 Ответить
13. fromtomike 48 29.09.16 12:12 Сейчас в теме
С удивлением обнаружил, что запрос типа:

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

Показать


Вернет все элементы справочника
15. herfis 500 29.09.16 12:20 Сейчас в теме
А еще, а еще!
Еще в 1С NULL в некоторых случаях физически содержится в полях данных.
Например, NULL записывается в те реквизиты элементов справочников, для которых в конфигураторе указано, что они доступны только для группы. И еще где-то, но я уже забыл :)
19. vadim1011985 100 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 100 29.09.16 13:37 Сейчас в теме
(20) necropunk, мне повезло больше - часа 3 отлавливал. Удивительно что они его еще не исправили за столь длительный срок.
22. caponid 29.09.16 15:02 Сейчас в теме
(19) надо для параметров &НачалоПериодаДействи и &КонецПериодаДействия использование установить в "Всегда"
23. vadim1011985 100 29.09.16 16:53 Сейчас в теме
(22) caponid, А почему без этой галочки не работает ?
24. herfis 500 29.09.16 17:46 Сейчас в теме
Правильнее не "использовать всегда", а оформить кастомные параметры периодов виртуальных таблиц именно как параметры СКД - фигурными скобками. Тогда СКД не будет при автозаполнении фантазировать дефолтными параметрами СКД периодов виртуальных таблиц.
jobkostya1c_ERP; necropunk; +2 Ответить
29. docerman 71 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 89 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 может быть использован для разных целей, таких как указание на неопределенный результат для вычислений или как маркер для отметки отсутствия значения в таблице.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот