Гость
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / DB2, неожиданый результат выборки. / 12 сообщений из 12, страница 1 из 1
09.05.2015, 21:35
    #38955279
Guzya
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Возникла необходимость сравнить список с таблицей, соответственно создал таблицу и загрузил туда список(пусть будет таблица 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
10.05.2015, 06:10
    #38955340
DB2, неожиданый результат выборки.
Guzya,

в Б есть ID которые IS NULL...
для проверки этого предположения выполни:
select * from А where id NOT in (select id from Б where id IS NOT NULL );
и посмотри что будет...
...
Рейтинг: 0 / 0
10.05.2015, 09:27
    #38955355
Guzya
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Код: 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
10.05.2015, 12:00
    #38955386
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Потому что 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
10.05.2015, 14:59
    #38955409
Guzya
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Спасибо, попробую осмыслить.
...
Рейтинг: 0 / 0
10.05.2015, 15:16
    #38955415
DB2, неожиданый результат выборки.
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
10.05.2015, 16:32
    #38955421
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
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
10.05.2015, 17:15
    #38955433
Guzya
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Прошу прощения за глупый вопрос, но подскажите.
Если,

val1=12
val2=null

каким будет результат выражения val1 != val2 , true\false или null?
...
Рейтинг: 0 / 0
10.05.2015, 20:54
    #38955476
Hunterik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Запрос:
Код: 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
10.05.2015, 21:18
    #38955485
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Тогда лучше так:
Код: 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
10.05.2015, 21:18
    #38955486
Victor Metelitsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Упс, опечатка.
...
Рейтинг: 0 / 0
11.05.2015, 10:33
    #38955599
Guzya
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2, неожиданый результат выборки.
Товарищи, большое спасибо за ответы, и отдельное спасибо за примеры!!!
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / DB2, неожиданый результат выборки. / 12 сообщений из 12, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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