помогите понять как работает запрос "in (..null..)"

QEOS
Дата: 06.02.2013 15:33:24
есть такой запрос для примера:
select *
from (select 1 as ls union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8) as ls
where ls.ls in (
	select 1 union select 5 union select null
)

Результат: выборка с двумя строками
1
5


если мы ставим not в условие
select *
from (select 1 as ls union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8) as ls
where not ls.ls in (
	select 1 union select 5 union select null
)

то результат пустой

вот не понятна немного как работает mssql с этим встречающимся null в подзапросе, может кто-то может объяснить двумя словами?
Гость333
Дата: 06.02.2013 15:45:44
QEOS
ls.ls in (select 1 union select 5 union select null)

Это эквивалентно такой проверке:
ls.ls = 1 OR ls.ls = 5 OR ls.ls = null

Такая проверка для значений 1 и 5 возвращает TRUE.

QEOS
если мы ставим not в условие
not ls.ls in (select 1 union select 5 union select null)

А это эквивалентно такой проверке:
ls.ls <> 1 AND ls.ls <> 5 AND ls.ls <> null

Поскольку результат "ls.ls <> null" равен UNKNOWN, то проверка никогда не вернёт TRUE.

Null Values
Shakill
Дата: 06.02.2013 15:46:06
QEOS,

http://msdn.microsoft.com/en-us/library/ms177682.aspx
Any null values returned by subquery or expression that are compared to test_expression using IN or NOT IN return UNKNOWN. Using null values in together with IN or NOT IN can produce unexpected results.
Гость333
Дата: 06.02.2013 15:56:12
Shakill
unexpected results

Это не очень хорошее объяснение. Если понимать механизм, то results будут полностью expected.
Shakill
Дата: 06.02.2013 16:03:35
Гость333
Shakill
unexpected results

Это не очень хорошее объяснение. Если понимать механизм, то results будут полностью expected.

согласен. скорее всего, имелось в виду, что они не совсем очевидные для тех кто впервые сталкивается
invm
Дата: 06.02.2013 16:09:02
Гость333
ls.ls <> 1 AND ls.ls <> 5 AND ls.ls <> null
Согласно сугубо личному опыту, новички гораздо лучше воспринимают
not (ls.ls = 1 or ls.ls = 5 or ls.ls = null)
QEOS
Дата: 07.02.2013 10:32:02
invm
Гость333
ls.ls <> 1 AND ls.ls <> 5 AND ls.ls <> null
Согласно сугубо личному опыту, новички гораздо лучше воспринимают
not (ls.ls = 1 or ls.ls = 5 or ls.ls = null)


так вот такое описание как раз должно давать отбор..
Jovanny
Дата: 07.02.2013 10:36:38
Почему-то никто не упомянул SET ANSI_NULLS ...
iap
Дата: 07.02.2013 10:48:30
QEOS
invm
пропущено...
Согласно сугубо личному опыту, новички гораздо лучше воспринимают
not (ls.ls = 1 or ls.ls = 5 or ls.ls = null)


так вот такое описание как раз должно давать отбор..
Это почему же?
Если ls.ls IN(1,5), то
TRUE OR UNKNOWN = TRUE;
NOT TRUE = FALSE
Если ls.ls NOT IN(1,5), то
FALSE OR FALSE OR UNKNOWN = UNKNOWN;
NOT UNKNOWN = UNKNOWN
Таким образом ни разу TRUE не получается!
А WHERE пропускает только TRUE

Сходите по ссылке во втором посте
QEOS
Дата: 07.02.2013 10:49:31
Jovanny
Почему-то никто не упомянул SET ANSI_NULLS ...

наверно это не особо важный пункт..

в целом всем спасибо
впринципе понятно как это работает.. это нечто типа правила-исключения. ну что жбудем знать.