powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Поиск не по NULL
20 сообщений из 20, страница 1 из 1
Поиск не по NULL
    #36172712
Юзер3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ASE 15

Сдаюсь.
Как сделать поиск по нескольким реквизитам, если каждый раз требуется поиск только по части реквизитов, без дикой конструкции из IF'ов и чтобы не тормозило?

т.е. Хочу чтобы один и тотже запрос отрабатывал только по не NULL'евым переменным, а NULL'евые игнорил, не искал по ним.

Входящие данные ФИО
Можно искать по Фамилии, Имени, Отчеству, как по всем сразу, так и по отдельности.
Если указано Ф и О, а И = NULL, то по имени не ищется, а только по Ф и О и должны совпадать в одной записи все не NULL элементы.
т.е.
Ф = Иванов
И = NULL
О = Иванович

Иванов Иван Иванович - есть
Иванов Петр Иванович - есть
и
Иванов Иван Петрович - нету
Петров Иван Иванович - нету
Петров Иван Петрович - нету

По одному параметру работает прекрасно и быстро:
Код: plaintext
1.
2.
select * from Table where
LastName = @LastName and  @LastName is not null
но как добавить к этому остальные реквизиты не могу допереть...
Использование isnull(), case when end - вызывает тормоза запроса, хотя и позволяет сделать то что надо.
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174105
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не думаю что конструкция
Код: plaintext
LastName = @LastName and  @LastName is not null
на много быстрее, чем
Код: plaintext
LastName = ISNULL(@LastName ,LastName)
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174286
Юзер3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
golsa,

вообще-то быстрее
что тут думать, я практически проверял
и к тому же мне НЕ нужны все записи из таблицы, если переменная равна NULL
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174454
Sergey Orlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Юзер3,
А не проще ли оформить в виде процедуры которая вначале и разберет какой запрос конкретно выполнить
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174483
Mikle83
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если запользовать Like в следующей вариации:

select * from Table where
(LastName like '%' + IsNull(@LastName ,'') + '%')
AND (Name like '%' + IsNull(@Name,'') + '%')
AND (Patronymic like '%' + IsNull(@Patronymic,'') + '%')


только проконтролируйте, чтобы IsNull возвращал именно пустую строку а не пробел
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174508
Юзер3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sergey OrlovЮзер3,
А не проще ли оформить в виде процедуры которая вначале и разберет какой запрос конкретно выполнить
Вообще-то там 6 параметров, и они могут быть в любом сочетании, т.е. 36 вариантов селекта?.. %(
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174529
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mikle83 пишет:
> А если запользовать Like в следующей вариации:
>
> select * from Table where
> (LastName like '%' + IsNull(@LastName ,'') + '%')
> AND (Name like '%' + IsNull(@Name,'') + '%')
> AND (Patronymic like '%' + IsNull(@Patronymic,'') + '%')

Этот запрос -- неоптимизируемый.

Будет молотить всё таблицу, запись за записью.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174535
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Юзер3 пишет:

> Вообще-то там 6 параметров, и они могут быть в любом сочетании, т.е. 36
> вариантов селекта?.. %(

Если ты хочешь, чтобы это всё быстро работало, тебе возможно даже ещё
больше вариантов запроса придётся написать.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174546
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Юзер3 пишет:

> По одному параметру работает прекрасно и быстро:
>
> select * from Table where
> LastName = @LastName and @LastName is not null
>
> но как добавить к этому остальные реквизиты не могу допереть...

Первый совет, который хочется дать:
0) генерируй текст запроса на клиенте, так, чтобы он содержал только указанные
критерии поиска.

1) не используй хранимые процедуры.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174574
Юзер3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mikle83А если запользовать Like в следующей вариации:

select * from Table where
(LastName like '%' + IsNull(@LastName ,'') + '%')
AND (Name like '%' + IsNull(@Name,'') + '%')
AND (Patronymic like '%' + IsNull(@Patronymic,'') + '%')


только проконтролируйте, чтобы IsNull возвращал именно пустую строку а не пробел
Зачем мне Like, если я ищу конкретное значение?
И тормозит это.

Вот так работает как надо, только на большой таблице долго, индекс как раз по этим полям:
Код: plaintext
1.
2.
3.
4.
select * from Table where
((LastName = @LastName)or(@LastName is null)) and
((FirstName = @FirstName)or(@FirstName is null)) and
((MiddleName = @MiddleName)or(@MiddleName is null))
Запрос на одну только фамилию не нулевую даёт такую статистику IO:
scan count 1, logical reads: (regular=576821 apf=323 total=577144), physical reads: (regular=0 apf=0 total=0), apf IOs used=0
Прямой запрос на фамилию соответственно:
scan count 1, logical reads: (regular=80 apf=0 total=80), physical reads: (regular=5 apf=0 total=5), apf IOs used=0
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174804
Юзер3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv
Юзер3 пишет:

> Вообще-то там 6 параметров, и они могут быть в любом сочетании, т.е. 36
> вариантов селекта?.. %(

Если ты хочешь, чтобы это всё быстро работало, тебе возможно даже ещё
больше вариантов запроса придётся написать.

Да, ещё больше вариантов
Варианты = 2 в степени число параметров

Сделал такой страшный вид:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
declare @SelVariant varchar( 6 )

select @SelVariant = 
case when @LastName is null then '0' else '1' end +
case when @FirstName is null then '0' else '1' end +
case when @MiddleName is null then '0' else '1' end +
...

if @SelVariant = '100000'
select * from Table where LastName = @LastName

if @SelVariant = '010000'
select * from Table where FirstName = @FirstName

...

if @SelVariant = '111111'
...
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174836
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Юзер3Входящие данные ФИО
Можно искать по Фамилии, Имени, Отчеству, как по всем сразу, так и по отдельности.
Если указано Ф и О, а И = NULL, то по имени не ищется, а только по Ф и О и должны совпадать в одной записи все не NULL элементы.
IMHO Вам надо проработать саму постановку вопроса. Я лично сомневаюсь, что пользователь в большом списке людей может искать кого то не по фамилии, а только по имени или отчеству ... ибо в этом абсолютно нет никакого смысла для него - ну выведутся для него тысячи Александров - что с ними он будет делать дальше ? Если же Фамилия или ее первая часть есть всегда, тогда все проще - делайте индекс на поле Фамилии, а остальные условия добавляйте как (@Имя IS NULL OR @Имя = Имя) AND (@Отчество IS NULL OR @Отчество = Отчество) - работать будет быстро, так как по индексу поднимутся все однофамильцы (а не так уж много), а потом по фильтру отсеются по заданному имени или отчеству.
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174873
Юзер3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ASCRUSIMHO Вам надо проработать саму постановку вопроса. Я лично сомневаюсь, что пользователь в большом списке людей может искать кого то не по фамилии, а только по имени или отчеству ... ибо в этом абсолютно нет никакого смысла для него - ну выведутся для него тысячи Александров - что с ними он будет делать дальше ? Если же Фамилия или ее первая часть есть всегда, тогда все проще - делайте индекс на поле Фамилии, а остальные условия добавляйте как (@Имя IS NULL OR @Имя = Имя) AND (@Отчество IS NULL OR @Отчество = Отчество) - работать будет быстро, так как по индексу поднимутся все однофамильцы (а не так уж много), а потом по фильтру отсеются по заданному имени или отчеству.
Да не важно, сделал поиск по всем полям.
К тому же в базе есть такие китайцы, у которых есть только имя, или только фамилия...
Александров по имени врятли будут искать, а вот какого-нибудь Ю вполне возможно.
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174946
Mikle83
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С like запрос хоть и медленный зато будет отрабатывать именно так как вы хотите :)

Еще один вариант:

select * from Table where
((LastName = @LastName) OR (@LastName is null))
AND
((Name = @Name) OR (@Name is null))
AND
((Patronymic = @Patronymic) OR (@Patronymic is null))



тогда у вас в случае если один из параметров Null - по нему соотв. условие ставиться не будет
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36174967
golsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй все же конструкцию
Код: plaintext
1.
2.
3.
select * from Table where
LastName = ISNULL(@LastName ,LastName)
and FirstName= ISNULL(@FirstName,FirstName)
and MiddleName= ISNULL(@MiddleName,MiddleName)
а индекс всеравно будет использован только один - скорее всего на LastName - в порядке использования во where. Поэтому без перестройки запроса скорости на все случаи не дастичь
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36175018
Юзер3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mikle83Еще один вариант:

select * from Table where
((LastName = @LastName) OR (@LastName is null))
AND
((Name = @Name) OR (@Name is null))
AND
((Patronymic = @Patronymic) OR (@Patronymic is null))

Такой вариант уже был у меня самого, см. выше.

golsaПопробуй все же конструкцию
Код: plaintext
1.
2.
3.
select * from Table where
LastName = ISNULL(@LastName ,LastName)
and FirstName= ISNULL(@FirstName,FirstName)
and MiddleName= ISNULL(@MiddleName,MiddleName)
а индекс всеравно будет использован только один - скорее всего на LastName - в порядке использования во where. Поэтому без перестройки запроса скорости на все случаи не дастичь
Пробовал - сотни тысяч физических и логических чтений... как и в варианте выше.
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36175127
Фотография Ggg_old
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте генерировать текст запроса на клиенте и подставлять параметры в текст запроса явно а не через @variable. В этом случае, у асе есть шансы как-то оценить селективность всех трех составляющего ФИО и в зависимости от этого выбрать один из трех индексов. Если я не ошибаюсь, асе не умеет оценивать селективность подставляемых через переменную параметров в запрос или работает в этом случае не достаточно умно. Но и сама собой, в этом случае статистика по колонкам таблицы должны быть самая свежая.
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36175285
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Юзер3 пишет:

> Зачем мне Like, если я ищу конкретное значение?
> И тормозит это.

Если у тебя справа от LIKE будт конкретное значение, то это всё равно,
что =

>
> Вот так работает как надо, только на большой таблице долго, индекс как
> раз по этим полям:
>
> select * from Table where
> ((LastName = @LastName)or(@LastName is null)) and
> ((FirstName = @FirstName)or(@FirstName is null)) and
> ((MiddleName = @MiddleName)or(@MiddleName is null))

Так как раз НЕ НАДО,

пары
(LastName = @LastName)or(@LastName is null)

как раз тебе " оптимизируемость " запросов и испортят.

> Запрос на одну только фамилию не нулевую даёт такую статистику IO:
> scan count 1, logical reads: (regular=576821 apf=323 total=577144),
> physical reads: (regular=0 apf=0 total=0), apf IOs used=0

Тут индекс не берётся.


> Прямой запрос на фамилию соответственно:
> scan count 1, logical reads: (regular=80 apf=0 total=80), physical
> reads: (regular=5 apf=0 total=5), apf IOs used=0

а тут берётся.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36175293
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
golsa пишет:

> select * from Table where
> LastName = ISNULL(@LastName ,LastName)
> and FirstName= ISNULL(@FirstName,FirstName)
> and MiddleName= ISNULL(@MiddleName,MiddleName)

Это -- сразу же убить производительность.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Поиск не по NULL
    #36176155
Mikle83
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Юзер3Такой вариант уже был у меня самого, см. выше.
Честно - не нашел... Был другой вариант

LastName = @LastName and @LastName is not null

но это совершенно разные вещи
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Поиск не по NULL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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