Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Не тривиальное условие фильтра  [new]
Airilo
Member

Откуда:
Сообщений: 37
Добрый день! Я столкнулся с пикантной проблемой в таком запросе

Select 
    Atom.Record
From
    Atom
Where
	Atom.Field = 2 And CAST(Atom.Value as int) > 1400 Or
	Atom.Field = 3 Atom.Value = '2'

Atom.Record имеет тип varchar. В этом поле хранятся разнообразные данные, но если скажем Atom.Field = 2 тогда в нем хранятся только числа, если Atom.Field = 3 тогда это текст.
Проблема в том, что выполняя эту строчку Atom.Field = 2 And CAST(Atom.Value as int) SQL может
проверять вторую часть условия CAST(Atom.Value as int) даже если Atom.Field не равен 2. Я не понимаю как это может быть? Если первая часть условия не выполняется не имеет смысла выполнять и вторую.

Посоветуйте пожалуйста как мне организовать такой запрос
31 дек 09, 22:08    [8142047]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
ё
Guest
Airilo

Я не понимаю как это может быть? Если первая часть условия не выполняется не имеет смысла выполнять и вторую.

у МС СКЛ, может иметься другое мнение по поводу "нумерации" условий в запросе

Airilo

Посоветуйте пожалуйста как мне организовать такой запрос

разделите запрос на 2-а и объедините через UNION ALL
31 дек 09, 22:28    [8142067]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
Airilo
Member

Откуда:
Сообщений: 37
Разделить запрос нет возможности потому что таких условий будет много, их может быть 40. Кроме того разделять запросы это не производительно. И честно сказать я не знаю как разделить такое условие Atom.Field = 2 And CAST(Atom.Value as int) что бы не происходила ошибка.
31 дек 09, 23:05    [8142119]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
Airilo
Member

Откуда:
Сообщений: 37
Самое интересное, что убрать второе условие Or Atom.Field = 3 And CAST(Atom.Value as varchar) = '2' тогда все работает как надо.
31 дек 09, 23:21    [8142142]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
ё
Guest
Airilo
Разделить запрос нет возможности потому что таких условий будет много, их может быть 40. Кроме того разделять запросы это не производительно. И честно сказать я не знаю как разделить такое условие Atom.Field = 2 And CAST(Atom.Value as int) что бы не происходила ошибка.


...про "это не производительно" - давайте ненада

> как разделить такое условие Atom.Field = 2 And CAST(Atom.Value as int) что бы не происходила ошибка

вы же говорили что - "если скажем Atom.Field = 2 тогда в нем хранятся только числа"?
какая тогда ошибка?

имелось в виду
Select 
    Atom.Record
From
    Atom
Where
	Atom.Field = 2 And CAST(Atom.Value as int) > 1400 --Or

union all

Select 
    Atom.Record
From
    Atom
Where
	Atom.Field = 3 --?? вот это чиво, почему без AND? - Atom.Value = '2'

ну или, если есть предубеждение перед union all
можна с ISNUMERIC поигратся
типа так
select '123'
where 
	case 
		when ISNUMERIC('123')=1 then cast('123' as int)
		else 0
	end > 125
правда тут есть ньюансы в виде экспонент.представления числа
31 дек 09, 23:28    [8142154]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
ё
Guest
ё
...
правда тут есть ньюансы в виде экспонент.представления числа

а в вашем случае - ещё и дробные числа - бок
31 дек 09, 23:41    [8142167]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
Airilo
Member

Откуда:
Сообщений: 37
ё,

автор
вот это чиво, почему без AND?

Это я лишнее вырезал когда постил на форум. Еще раз покажу весь запрос:

Select 
    Atom.Record
From
    Atom
Where
	Atom.Field = 2 And CAST(Atom.Value as int) > 1400 
Or
	Atom.Field = 3 And Atom.Value = '2'


Спасибо за идею с Union возможно это мне поможет. Но от других идей я не отказываюсь, просто не могу поверить что придется делать с таким извратом.
1 янв 10, 02:46    [8142428]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
aleks2
Guest
Select 
    Atom.Record
From
    Atom
Where
	CASE Atom.Field 
                  when 2 then case when CAST(Atom.Value as int) > 1400 then 1 else 0 end
                  when 3 then case when  Atom.Value = '2' then 1 else 0 end 
                  else 0
             end =1 

Только так делать НЕ надо.
1 янв 10, 08:54    [8142552]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
Airilo
Member

Откуда:
Сообщений: 37
ё,

Похоже что Union мне помог. У меня получилось обойтись всего одним Union, за счет того что я сгруппировал все условия, числовые в один селект строковые в другой. И что удивительно мне не пришлось использовать Cast для числовых условий. Правда сказать план выполнения стал длиннее :). В общем спасибо.
1 янв 10, 18:51    [8143084]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
Airilo
Member

Откуда:
Сообщений: 37
Вот еще возник закономерный вопрос, как все это дело отсортировать по полю, которое мне совершенно не нужно возвращать в запросе? :)
1 янв 10, 21:31    [8143143]     Ответить | Цитировать Сообщить модератору
 Re: Не тривиальное условие фильтра  [new]
ё
Guest
всё заключить во внешний СЕЛЕКТ
...по крайней мере, я другого способа - не знаю
1 янв 10, 21:35    [8143146]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить