powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / DB2, неожиданый результат выборки.
12 сообщений из 12, страница 1 из 1
DB2, неожиданый результат выборки.
    #38955279
Guzya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возникла необходимость сравнить список с таблицей, соответственно создал таблицу и загрузил туда список(пусть будет таблица A). Сравниваю с таблицей Б по полю ID.
Таблица А - 196 записей.
Таблица Б - 210 000 записей.
DB2 9.7.9 (windows)

Делаю:
Код: plsql
1.
select * from А where id in (select id from Б);


получаю 51 запись.

Делаю:
Код: plsql
1.
select * from А where id NOT in (select id from Б);


и НЕОЖИДАННО, вместо 145 записей получаю 0.

А вот если:
Код: plsql
1.
select * from А where id NOT in (select id from А where id in (select id from Б));


то результат верный, 145 записей.

Уточню, после создания таблицы А ни сбора статистики, ни чего еще не проводилось(даже db2 не перезапускал).

Второй раз с таким сталкиваюсь, оба раза ситуация возникала с новыми(временными) таблицами созданными для оперативного сравнения списков.

Подозреваю, что дело в каком-нибудь оптимизаторе запросов, но моих знаний не достаточно для точных выводов.

Какие будут идеи?
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955340
Guzya,

в Б есть ID которые IS NULL...
для проверки этого предположения выполни:
select * from А where id NOT in (select id from Б where id IS NOT NULL );
и посмотри что будет...
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955355
Guzya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plsql
1.
select * from А where id NOT in (select id from Б where id IS NOT NULL);


результат правильный.

Но,
Код: plsql
1.
SELECT * FROM А where id is null


пусто.

Объясните пожалуйста на пальцах, почему.
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955386
Victor Metelitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Потому что where a=null пусто и where not(a=null or неважно-что) тоже пусто, а in (логически) это вариант or.

Кстати, есть момент с null'ами, про который не предостерегают, на него легко не обратить внимание, а он важен:

Когда where undefined или where false, нет разницы - выборка пуста. Но для constraint'ов check(undefined) или check(false) ведут себя по-разному, undefined не мешает добавить строку в таблицу. Нет нужды и даже вредно писать вещи вроде
check xxx constraint(FIO is null or FIO=upper(FIO))
кода с тем же эффектом можно
check xxx constraint(FIO=upper(FIO))
(оптимизатор будет благодарен)

"For example, CHECK (salary + bonus > 30000) is accepted if salary is set to NULL, because CHECK constraints must be either satisfied or unknown, and in this case, salary is unknown. However, CHECK (salary IS NOT NULL) would be considered false and a violation of the constraint if salary is set to NULL."
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955409
Guzya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, попробую осмыслить.
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955415
Victor MetelitsaПотому что where a=null пусто и where not(a=null or неважно-что) тоже пусто, а in (логически) это вариант or.Виктор, при всем моем уважении, позволь не согласиться с тобой... Точнее, слегка тебя подправить.

Вся соль тут в том, что предикат IN эквивалентен OR-у, как ты и сказал, но вот предикат NOT IN эквивалентен AND-у.
То есть,
Код: sql
1.
<поле> IN (val1, val2, ... , valN)

по сути будет обрабатываться так:
Код: sql
1.
<поле> = va1 OR <поле> = val2 OR ... OR <поле> = valN



в то время, как
Код: sql
1.
<поле> NOT IN (val1, val2, ... , valN)

будет обрабатываться так:
Код: sql
1.
<поле> != val1 AND <поле> != val2 AND ... AND <поле> != valN



А вот теперь начинает работать SQL-булева алгебра. И тут, всё же (это как раз исправление-дополнения к твоему высказыванию) NULL OR TRUE дает TRUE. В то время как NULL AND TRUE дает NULL, который трактуется, по сути, как FALSE. Именно поэтому IN вернул автору чего-то, а NOT IN - ничего не вернул.
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955421
Victor Metelitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
not (a or b) = (not a) and (not b)

Проверка:

not (F or F) = not(F) = T
not (F or T) = not(T) = F
not (T or T) = not(T) = F

not (U or U) = not(U) = U
not (U or F) = not(U) = U
not (U or T) = not(T) = F

not (F) and not(F) = T and T = T
not (F) and not(T) = T and F = F
not (T) and not(T) = F and F = F

not (U) and not(U) = U and U = U
not (U) and not(F) = U and T = U
not (U) and not(T) = U and F = F
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955433
Guzya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения за глупый вопрос, но подскажите.
Если,

val1=12
val2=null

каким будет результат выражения val1 != val2 , true\false или null?
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955476
Фотография Hunterik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with A as (
select
cast(12 as integer) val1
from sysibm.sysdummy1
)
,
B as (
select
cast(null as integer) val2
from sysibm.sysdummy1
)
select
(case when val1 != val2 then 1 else 0 end) cmp1
, (case when val1 = val2 then 1 else 0 end) cmp2
from a,b


Ответ:
Код: sql
1.
2.
3.
 CMP1 CMP2
 ---- ----
    0    0
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955485
Victor Metelitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда лучше так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
with
  A(val1) as (
    values(cast(12 as integer))
  ),
  B(val2) as (
    values(cast(null as integer))
  )
select
  (case 
     when val1 != val2 then '!='
     when val1 =  val2 then '='
     else 'UNDEFINED'
  )
from A,B
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955486
Victor Metelitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, опечатка.
...
Рейтинг: 0 / 0
DB2, неожиданый результат выборки.
    #38955599
Guzya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Товарищи, большое спасибо за ответы, и отдельное спасибо за примеры!!!
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / DB2, неожиданый результат выборки.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]