:: Visual Foxpro, Foxpro for DOS
case в where Оракл
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Запутался в какой-то ерунде.
Есть мной же написанные огромные процедуры,
в основном много уровневый запросы
Появилась необходимость сделать в них банальный
переключатель по содержанию некого поля
Добавил еще параметр в процедуры
lwy in integer
Рулить нужно по полю таблицы acgr
docnum есть ли единица в первом символе или ее там нет,
или неважно.
Простые запросы в эту таблицу
типа select count(*) from aggr where trim(substr(docnum,1,1)='1') , ... trim(substr(docnum,1,1)!='1'
дают разное число записей, что есть верно
Теперь залезаю в процедуры и в существующем where, где есть указанная таблица
с алиасом b дописываю
and case when lwy=0 then 1 when lwy =1 and trim(substr(b.docnum,1,1))='1' then 1 case lwy =2 and trim(substr(b.docnum,1,1))!='1' then 1 end=1
Тестирую с тремя разными lwy -0,1,2 и получаю совершенно неожиданно одинаковые результаты по сумма , что не есть верно.
Заменяю case на банальные and ((lwy=0) or (lwy=1 and trim(substr(b.docnum,1,1))='1') or (lwy =2 and trim(substr(b.docnum,1,1))!='1'))
и все верно, суммы для разных lwy разные, но вроде так плохо для оптимизации.
Что неверно в случае case не понимаю, вроде это одно и тоже.
Самое поганое, не проверив результат уже 12 процедур поменял с case



Исправлено 1 раз(а). Последнее : boba, 02.10.21 21:30
Ratings: 0 negative/0 positive
Re: case в where Оракл
sphinx

Сообщений: 31182
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Ничего не понял. Может потому, что у меня нет таблиц и процедур.


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive
Re: case в where Оракл
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Но вот есть место в середине процедуры, где в where
уже есть условия на упомянутую таблицу.
Добавляю в условие and case ....
с параметром lwy =0,1,2
При котором нужно для 0 условие не менять,
при lwy=1 и trim(substr(docnum,1,1))!='1'
при lwy =2 и trim(substr(docnum,1,1))='1'
Добавляю в where указанный case
получаю совершенно одинаковые независимо
от lwy результаты
Ratings: 0 negative/0 positive
Re: case в where Оракл
sphinx

Сообщений: 31182
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Может лучше так:
substr(trim(docnum, 1, 1))

Ведь если ВПЕРЕДИ один пробел - он и у тебя сначала отрежется слева, а потом превратится в пустое значение (после trim).


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive
Re: case в where Оракл
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Завтра на работе проверю, но скорее всего так и написал,
а тут ошибся
Ratings: 0 negative/0 positive
Re: case в where Оракл
sphinx

Сообщений: 31182
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Цитата:
Теперь залезаю в процедуры и в существующем where, где есть указанная таблица
с алиасом b дописываю

and
case when lwy=0
then 1
when lwy=1 and trim(substr(b.docnum,1,1))='1'
then 1
case (WHEN-?) lwy =2 and trim(substr(b.docnum,1,1))!='1'
then 1
end = 1


Здесь CASE всегда вернет 1, а значит от параметра lwy запрос никак не зависит.
Обычно проверяют как-то так:

and
case when lwy=0
then 1
when substr(trim(b.docnum), 1, 1)) = '1'
then 2
when substr(trim(b.docnum), 1, 1)) <> '1'
then 3
end


------------------
"Veni, vidi, vici!"(с)




Исправлено 3 раз(а). Последнее : sphinx, 03.10.21 08:40
Ratings: 0 negative/0 positive
Re: case в where Оракл
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Ну и как ты такое в where поместишь,
если там возврат то 1 то 2
я же сравниваю весь блок с 1
case end=1
lwy на входе имеет одно из значений
0, 1, 2
Отдали 1, нужно чтобы сработала ветка
subtr(trim(numdoc),1,1)='1'
при lwy =2 ветка subtr(trim(numdoc),1,1)!='1'
поэтому всегда и возвращаю 1
Ratings: 0 negative/0 positive
Re: case в where Оракл
sphinx

Сообщений: 31182
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Легко. Кинь оригинальный запрос и тестовые данные.


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive
Re: case в where Оракл
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Это все на работе
Не модифицированный код одной из 25 процедур ниже
В него добавлен lwy int integer,
Cама упомянутая модификация в этом месте
____________________________________________________
where b.codgr = a.codgr
and b.period between per1 and per2
and b.codplan =
3705763001
and case ..... end =1 ( это вставка, про которую говорил)
При lwy=1 b lwy =2 результат в цифрах должен отличаться от lwy =0

_________________________________________________________

procedure usrfsd76(per1 in integer,
per2 in integer,
p_cursor out t_SLRCursor) is
begin
open p_cursor for
select case
when f10022 != ' ' then
'{' || substr(f10022, 1, 6) || '}' || substr(f10022, 7)
else
' '
end as f10022,
case
when f10023 != ' ' then
'{' || substr(f10023, 1, 6) || '}' || substr(f10023, 7)
else
' '
end as f10023,
F_M0210,
F_M0908,
F_M0202,
F_M0201,
F_M0213,
F_M0209,
F_M0204,
lnone
from (select *
from (select f6004,
f10022,
f10023,
f5100,
sum(case
when flagcredit = 1 then
-smr
else
smr
end) as smr
from (select case
when ss.nminref = '_КОНСОЛИДАЦИЯ' then
' '
else
aa.nminref
end as f10022,
case
when ss.nminref = '_КОНСОЛИДАЦИЯ' then
' '
else
bb.nminref
end as f10023,
cc.nminref as f5100,
case
when ss.nminref = '_КОНСОЛИДАЦИЯ' then
'_КОНСОЛИДАЦИЯ'
else
'Не Консолидация'
end as f6004,
kk.codtr,
kk.flagcredit,
kk.smr
from (select max(f3711317001) as f3711317001,
max(f3706422001) as f3706422001,
max(f3706983001) as f3706983001,
max(f3170404001) as f3170404001,
max(f3572367001) as f3572367001,
flagcredit,
codtr,
smr,
count(*)
from (select decode(f.codref,
3711317001,
f.codinref) as f3711317001,
decode(f.codref,
3706422001,
f.codinref) as f3706422001,
decode(f.codref,
3706983001,
f.codinref) as f3706983001,
decode(f.codref,
3170404001,
f.codinref) as f3170404001,
decode(f.codref,
3572367001,
f.codinref) as f3572367001,
flagcredit,
codtr,
smr
from (select c.codref,
c.codinref,
c.flagcredit,
a.codtr,
sum(a.summaincur) as smr
from acctrans a,
acctransgr b,
acctransref c
where b.codgr = a.codgr
and b.period between per1 and per2
and b.codplan =
3705763001
and a.codtr = c.codtr
and ((a.accc = 76 and
c.flagcredit = 1) or
(a.accd = 76 and
c.flagcredit = 0))
group by a.codtr,
c.flagcredit,
c.codref,
c.codinref
order by a.codtr,
c.flagcredit,
c.codref,
c.codinref) f)
where f3711317001 is not null
or f3706422001 is not null
or f3706983001 is not null
or f3170404001 is not null
group by codtr, flagcredit, smr
order by codtr, flagcredit) kk
left outer join refuser aa
on aa.codref = 3711317001
and kk.f3711317001 = aa.codinref
left outer join refuser bb
on bb.codref = 3706422001
and kk.f3706422001 = bb.codinref
left outer join refuser cc
on cc.codref = 3706983001
and kk.f3706983001 = cc.codinref
left outer join (select case
when nvl(t.value, '0') = 0 then
tt.nminref
else
'_КОНСОЛИДАЦИЯ'
end as nminref,
tt.codinref
from REFITEMATTR t,
refuser tt
where t.codref = 3170404001
and codattr = 3715605001
and tt.codref = 3170404001
and tt.codinref =
t.codinref) ss
on kk.f3170404001 = ss.codinref
left outer join refuser ee
on ee.codref = 3572367001
and kk.f3572367001 = ee.codinref)
group by f6004, f10022, f10023, f5100, flagcredit
order by f6004 asc, f10022, f10023, f5100, flagcredit)

PIVOT(SUM(smr) for f5100 in('',

'F_M0210 ПРОЧИЕ ОБОРОТЫ' as
F_M0210,
'F_M0908 КУРСОВЫЕ РАЗНИЦЫ' as
F_M0908,
'F_M0202 РАСЧЕТЫ ДЕНЕЖНЫМИ СРЕДСТВАМИ' as
F_M0202,
'F_M0201 РЕАЛИЗАЦИЯ С НДС (КТ 90)' as
F_M0201,
'F_M0213 ЗАЧЕТ АВАНСА' as
F_M0213,
'F_M0209 КУРСОВАЯ РАЗНИЦА' as
F_M0209,
'F_M0204 Взаимозачет задолженности' as
F_M0204 ,
'NULL НЕ ОПРЕДЕЛЕНО' as
lnone

))
order by f6004 asc, f10022, f10023);
end usrfsd76;
Ratings: 0 negative/0 positive
Re: case в where Оракл
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Ratings: 0 negative/0 positive
Re: case в where Оракл
PaulWist

Сообщений: 14620
Дата регистрации: 01.04.2004
boba
Теперь залезаю в процедуры и в существующем where, где есть указанная таблица
с алиасом b дописываю
and case when lwy=0 then 1 when lwy =1 and trim(substr(b.docnum,1,1))='1' then 1 case lwy =2 and trim(substr(b.docnum,1,1))!='1' then 1 end=1

Володь, так выражение
case when lwy=0 then 1 when lwy =1 and trim(substr(b.docnum,1,1))='1' then 1 case lwy =2 and trim(substr(b.docnum,1,1))!='1' then 1 end=1

всё равно приведёт к сканированию таблицы, оно ничем не отличается от OR, за исключением когда lwy=0.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 2 раз(а). Последнее : PaulWist, 03.10.21 22:10
Ratings: 0 negative/0 positive
Re: case в where Оракл
sphinx

Сообщений: 31182
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Только на работе. Если воссоздан проблему. Нет там ничего, или ошибка синтаксиса (как показал) или логики. Я не сказал, что уже мне в, е понятно.. Мы все исходим из предположений.

Смогу воссоздать проблему - там будет видно. Удачи, Володя.


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 18 (Гостей: 18)

© 2000-2024 Fox Club 
Яндекс.Метрика