powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / WHERE с переменным числом условий
15 сообщений из 15, страница 1 из 1
WHERE с переменным числом условий
    #32051752
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сразу прошу прощения, если мой вопрос FAQовый.
Что-то я не могу сообразить как сделать такую в общем-то достаточно стандартую вещь.
Есть две таблицы t1 и t2. Необходимо найти пересечение их по нескольким полям. Однако! NULL в полях надо интерпретировать в соответствии с теорией реляционных БД - равен любому значению.
То есть
t1
f1 f2 f3
--------------
1 А 10
2 NULL 20
3 В 20

t2
f11 f12 f13
--------------
1 А 10
2 Б 20
3 В 20
4 Г 20
5 Д 30

Пересекаем по f2 <-> f12 и f3 <-> f13
Результат
f1 f2 f3 f11 f12 f13
---------------------------------
1 А 10 1 А 10 <-- точное совпадение
2 NULL 20 2 Б 20 <-- неточное совпадение
2 NULL 20 3 В 20 <-- неточное совпадение
2 NULL 20 3 Г 20 <-- неточное совпадение
3 В 20 3 В 20 <-- точное совпадение

Надеюсь понятно.
Если надо дополнительно разъяснить, то прошу.
Спасибо всем откликнувшимся.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051753
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ой блин.... зарапортовался...
результат

f1 f2 f3 f11 f12 f13
---------------------------------
1 А 10 1 А 10 <-- точное совпадение
2 NULL 20 2 Б 20 <-- неточное совпадение
2 NULL 20 3 В 20 <-- неточное совпадение
2 NULL 20 4 Г 20 <-- неточное совпадение
3 В 20 3 В 20 <-- точное совпадение
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051756
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, надо что-то делать мне с собой... Не могу сразу всё написать :)
Главное условие! Должно работать быстро, то есть использовать индексы. Можно использовать дополнительные поля, функциональные индексы, что угодно.
В одну сторону я сделал
where f2 like ISNULL(f12, '%')
но хочется в обе.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051846
dao
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А может подойти с другой стороны? сначала построить декартово произведение а потом убрать лишнее? но это выгодно бутет если убираемых строк не много.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051851
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько я знаю реляционные основы БД, декартово произведение строится просто при перечислении доменов во FROM. А вот как убрать лишнее? Это вопрос :)
Кто из великих скульпторов сказал, Роден что ли, что ваять скульптуры просто - берёшь глыбу и отсекаешь всё лишнее. :)
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051855
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Опять забыл написать :) всё-таки надо что-то с головой делать...
Я почему так тему-то назвал? Идея такова, что при встрече NULLа в поле слева или справа, это условие как бы убирается из рассмотрения.
То есть получается, что для неNULLовых полей f1 или f11 условие выглядит так
WHERE f1 = f11 AND f2 = f12
а если в записи в f1 или f11 есть NULL, то условие приевращается (брюки превращаются...)
WHERE f2 = f12
Вот и получается, что в WHERE число условий переменное и зависит от содержания полей.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051859
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так вот:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
 -- preparing workspace --
 
create table test1 (f1 int null,f2 char( 3 ) null,f3 int null)
go
create table test2 (f11 int null,f12 char( 3 ) null,f13 int null)
go
insert test1 (f1,f2,f3) values( 1 ,'А', 10 )
insert test1 (f1,f2,f3) values( 2 ,null, 20 )
insert test1 (f1,f2,f3) values( 3 ,'В', 20 )
go
insert test2 (f11,f12,f13) values( 1 ,'А', 10 )
insert test2 (f11,f12,f13) values( 2 ,'Б', 20 )
insert test2 (f11,f12,f13) values( 3 ,'В', 20 )
insert test2 (f11,f12,f13) values( 4 ,'Г', 20 )
insert test2 (f11,f12,f13) values( 5 ,'Д', 30 )
go

 -- selecting data --
 
select * from test1 t1, test2 t2
where (t1.f2 = t2.f12 and t1.f3 = t2.f13)
    or ( coalesce(t1.f2,'NULL') = 'NULL' and t1.f3 = t2.f13)
go

 -- get results --
 
f1          f2   f3          f11         f12  f13         
 ----------- ---- ----------- ----------- ---- ----------- 
 
 1 . 00         А     10 . 00         1 . 00         А     10 . 00 
 2 . 00         NULL  20 . 00         2 . 00         Б     20 . 00 
 2 . 00         NULL  20 . 00         3 . 00         В     20 . 00 
 2 . 00         NULL  20 . 00         4 . 00         Г     20 . 00 
 3 . 00         В     20 . 00         3 . 00         В     20 . 00 

( 5  row(s) affected)
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051872
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Jimmy
Не то - план смотрел?
Там table scan с обеих сторон

create index ndxt1f1 on test1(f1)
create index ndxt1f2 on test1(f2)
create index ndxt1f3 on test1(f3)
create index ndxt2f11 on test2(f11)
create index ndxt2f12 on test2(f12)
create index ndxt2f13 on test2(f13)
не помогает - убирается table scan с одной только, а хотелось бы с обеих.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051891
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KonstN
Я знаю точно одну вещь - нельзя заниматься оптимизацией прямо в процессе разработки, когда нет еще полной картины работающей системы, т.к.:

0. В первую очередь нужно реализовать конкретную задачу . В нашем случае - получить конкретную выборку

1. План запроса сильно зависит от количества записей , и при малых объемах оптимизатору действительно препочтительнее использовать Table scan, т.к. быстрее будет.

2. Даже если план запроса кажется неоптимальным, производительность может быть вполне удовлетворительной и пользователи просто не заметят
результатов оптимизации.

4. Оптимизируя какой-либо запрос можно существенно замедлить прочие операции, т.к. количество индексов и качество индексов влияет на INSERT|UPDATE операции.

Поэтому, вплотную оптимизацией стоит заниматься только если пользователи реальной системы об этом просят и согласны пойти на некоторые жертвы в части другой функциональности.
Причем, это не мои идеи, а принципы экстремального программирования - ИМХО достаточно верной методики создания ПО малыми коллективами в короткие сроки.

ЗЫ А для оптимизации (если она действительно нужна ) попробуй воспользоваться Index Tuning Wizard'ом.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051918
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Jimmy
0. конкретная задача - получить вышеуказанную выборку наиболее быстрым способом, что, как правило, происходит при index seek в указанных условиях
1. таблицы очень не маленькие - с одной стороны полмиллиона и с другой полста тысяч
да, при малых объёмах table scan может быть быстрее, но дело в том, что план твоего запроса не изменится при увеличении количества записей, всё равно скан будет, что неприемлемо
2. производительность в высшей степени неудовлетворительна - реальная задача выполняется шесть часов, правда, там есть дополнительные служебные вызовы
была бы удовлетворительна, сюда бы не писал - нет пока времени для теоретических умствований
4. истину глаголешь! однако я ничего не говорил про DML операции, мне нужен быстрый select, не зря ж упомянул фун. индексы и доп. поля

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

ЗЫ Index Tuning Wizard может помочь только с настройкой индексов для определённых запросов. А у меня он ещё не определён! А для твоего запроса с table scanом он вообще как собаке стоп-сигнал поможет.

Принципы ХР тут совсем ни к чему - задача стоит конкретнее некуда, нужна идея, а не принципы.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051932
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну ладно, попробую поконкретней свою мысль выразить: " Что толку мне смотреть на план выполнеия запроса, если у меня в таблицах макс. 5 записей (см. п.1) и никакой информации об индексах?"

ЗЫ Извини, что обидел тебя своими " теоретическими умствованиями ", но неплохо было бы сначала воспроизвести все условия задачи, а уж потом о конкретике ратовать.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051955
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Table scan для второй таблице вполне оправдан, т.к. в условии используется функция COALESCE().
Для преодоления такой несправедливости можно попробовать ввести добавочное поле-флаг:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
alter table test1 add is_null smallint default  0 
go
update test1 set is_null =  1  where coalesce(f2,'NULL')='NULL'
go
create index idx_is_null on test1 (is_null)
go
create index idx_f2 on test1 (f2)
go
create index idx_f3 on test1 (f3)
go
create index idx_f12 on test2 (f12)
go
create index idx_f13 on test2 (f13)
go

select * from test1 t1, test2 t2
where (t1.f2 = t2.f12 and t1.f3 = t2.f13)
    or ( t1.f3 = t2.f13 and t1.is_null =  1 )


ЗЫ Возможно , это улучшит дело, но мой план запроса - в обеих случаях Table scan. К тому же селективность индекса по полю-признаку мала, так что и на больших объемах оптимизатор скорее всего не будет его использовать.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051969
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Jimmy
Ну извини, что обидел насчёт плана.
Но просто там невооружённым глазом видно, что скан будет - слева функция. Из такой ситуации выход только индекс на функцию. Или доп. поле, как ты сделал. А селективность зависит от того сколько там NULLов будет.
Однако вариант с доп.полями не очень хорош, потому как ORы сразу портят всю малину. Да и прикинь сколько нужно вариантов перебрать - полей-то несколько сравнивается.
Вот с likeом очень хорошо получается, как я написал. Но только в одну сторону...
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051974
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну я бы еще попробовал увеличить селективность индекса путем создания составного:
create index idx_f2_is_null on test1 (f2,is_null)

Но это к сожалению все, что я могу "родить".

ЗЫ Без обид.
...
Рейтинг: 0 / 0
WHERE с переменным числом условий
    #32051992
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я что-то отвлёкся :)
Такое поле {0,1} не очень-то нужно - MSSQL превосходно справляется с индексированием по NULLам, и запросы оптимизирует с учётом их статистики, вот у Оракла, там есть с этим проблемы, там по NULLам всегда скан идёт (если не вру :)).
Надо просто сделать так, что NULL в одном поле равен любому значению в соотвествующем. Это вот достигается или likeом с % или исключением этого условия для этих строк. Или ещё чем-то. Вот чем? Тут хотя бы знать даже, что это невозможно, чтоб не мучиться, а успокоиться. :)
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / WHERE с переменным числом условий
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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