CftClub.ru
Клуб специалистов ЦФТ-Банк

CASE WHEN THEN ошибка
На страницу 1, 2  След.
 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle
Предыдущая тема :: Следующая тема  
Автор Сообщение
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеПн Июл 16, 2018 15:58   CASE WHEN THEN ошибка Ответить с цитатой
Полезность: Нет оценки
Коллеги, приветствую

1 вариант работает без ошибок, 2ой вариант с ошибкой... разницу особо не вижу(за исключением CASE WHEN THEN, который возвращает тот же самый набор)
В чём причина ошибки?

Цитата:
В настоящий момент операция невозможна:
подзапрос одиночной строки возвращает более одной строки



CLASS_ varchar2(100) := 'CL_PRIV';
P_CLIENT ref [CL_PRIV] := 12160074117;
cnt number;
begin
--------------------------------------------------------------------------
-- 1 вариант
debug(p_client.[LINKS_OTHER],0);

select z(sum(z.c)) in
(

select x(count(x) :c ) in ::[AC_FIN] all
where x.[CLIENT_V] in (
(
select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
)
and x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')

)
into cnt;
debug(cnt,0);

--------------------------------------------------------------------------
-- 2 вариант
select z(sum(z.c)) in
(

select x(count(x) :c ) in ::[AC_FIN] all
where x.[CLIENT_V] in (case
when class_ in ('CL_ORG')
then (p_client)
when class_ in ('CL_PRIV')
then
( select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
end)
and x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')

)
into cnt;
debug(cnt,0);
end;
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеПн Июл 16, 2018 16:09    Ответить с цитатой
Полезность: Нет оценки
then
( select distinct w(w.[PARTNER]) [/i]
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеПн Июл 16, 2018 16:13    Ответить с цитатой
Полезность: Нет оценки
vtar пишет:
then
( select distinct w(w.[PARTNER]) [/i]


Ошибка повторилась...

1 ый вариант работает... без distinct)

это то меня и смущает ... внутри case тоже самое что в 1 варианте... а работает по разному...
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеПн Июл 16, 2018 16:18    Ответить с цитатой
Полезность: 1
можно 2-й переписать, вместо case - склеить union all


select x(count(x) ) in

(

select z (z) in .

union all

select z (z) in .

)
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеПн Июл 16, 2018 16:20    Ответить с цитатой
Полезность: Нет оценки
vtar пишет:
можно 2-й переписать, вместо case - склеить union all


select x(count(x) ) in

(

select z (z) in .

union all

select z (z) in .

)



Тоже так думаю, там правда из двух источников union получится 4 тогда...)
Сейчас попробую...


В общем попробовал... заработал...сенкс... непонятно правда чем ему case не угодил

В итоге получилось так

[code]
/* Оригинал до 2018.07.16
----------------------------------------
select x(count(x) :c ) in ::[AC_FIN] all
where x.[CLIENT_V] in (case
when class_ in ('CL_ORG')
then (p_client)
when class_ in ('CL_PRIV')
then
( select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
end)
and x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')
----------------------------------------
union all

select x(count(x) : c) in ::[AC_FIN] all
where x.[CLIENT_V] in (case
when class_ in ('CL_ORG')
then (p_client)
when class_ in ('CL_PRIV')
then
( select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
end)
and x.[COM_STATUS] is null
*/
-- Е.Е.Матвеев 2018.07.16
----------------------------------------
select x(count(x) :c ) in ::[AC_FIN] all
where x.[CLIENT_V] in (p_client)
and class_ in ('CL_ORG')
and x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')

union all
----------------------------------------
select x(count(x) :c ) in ::[AC_FIN] all
where x.[CLIENT_V] in
(select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
and class_ in ('CL_PRIV')
and x.[COM_STATUS] != ::[COM_STATUS_PRD]([code]='TO_OPEN')

union all
----------------------------------------
select x(count(x) : c) in ::[AC_FIN] all
where x.[CLIENT_V] in (client)
and class_ in ('CL_ORG')
and x.[COM_STATUS] is null

union all
----------------------------------------
select x(count(x) : c) in ::[AC_FIN] all
where x.[CLIENT_V] in ( select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
and class_ in ('CL_PRIV')
and x.[COM_STATUS] is null


)
----------------------------------------
into cnt;
[/code]
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеВт Июл 17, 2018 09:23    Ответить с цитатой
Полезность: Нет оценки
select (count) должен быть один из всей выборки соединенной по union all
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеВт Июл 17, 2018 09:41    Ответить с цитатой
Полезность: Нет оценки
vtar пишет:
select (count) должен быть один из всей выборки соединенной по union all


Приветствую, не совсем тебя понял... старая реализация схематично была такой

select sum() in
[
select count()
1ый CASE WHEN THEN
union all
select count()
2ой CASE WHEN THEN
]
into cnt

Новая реализация, без использования CASE WHEN THEN

select sum() in
[
select count()
where фильтр - соответствующая часть 1ого CASE
union all
select count()
where фильтр - соответствующая часть 1ого CASE
union all
select count()
where фильтр - соответствующая часть 2ого CASE
union all
select count()
where фильтр - соответствующая часть 2ого CASE
]
into cnt

Получается сумма по count, ... условно говоря sum по [2,3,4,5] = 14
dburg
Участник


Вступление в Клуб: 29.01.2015
СообщениеВт Июл 17, 2018 10:43    Ответить с цитатой
Полезность: Нет оценки
Всем привет.
Так не поможет?
select w( ANALYTIC( LISTAGG(w.[PARTNER], ','),'WITHIN GROUP (ORDER BY [1])', null ) )
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеВт Июл 17, 2018 12:10    Ответить с цитатой
Полезность: Нет оценки
Матвеев Евгений пишет:
vtar пишет:
select (count) должен быть один из всей выборки соединенной по union all


Приветствую, не совсем тебя понял... старая реализация схематично была такой

select sum() in
[
select count()

Получается сумма по count, ... условно говоря sum по [2,3,4,5] = 14


А, тогда нормально все. Не увидел sum.
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеВт Июл 17, 2018 12:41    Ответить с цитатой
Полезность: Нет оценки
vtar пишет:
Матвеев Евгений пишет:
vtar пишет:
select (count) должен быть один из всей выборки соединенной по union all


Приветствую, не совсем тебя понял... старая реализация схематично была такой

select sum() in
[
select count()

Получается сумма по count, ... условно говоря sum по [2,3,4,5] = 14


А, тогда нормально все. Не увидел sum.



Правильно не увидел), он расположен до
/* Оригинал до 2018.07.16
----------------------------------------
и я его не менял...

Там же в конце конструкции всё равно стоит
----------------------------------------
into cnt;

цель была либо понять почему CASE так так себя ведет, либо отказаться от его использования...

Кстати я таки и не понял, почему он надлежащим образом не работает... формально для случая

CLASS_ varchar2(100) := 'CL_PRIV';

они обе вроде как должны одинаково работать...
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеВт Июл 17, 2018 12:45    Ответить с цитатой
Полезность: Нет оценки
dburg пишет:
Всем привет.
Так не поможет?
select w( ANALYTIC( LISTAGG(w.[PARTNER], ','),'WITHIN GROUP (ORDER BY [1])', null ) )


Привет... привет...

...важно не менять логику выполнения исходного кода... а перепроектировать средства реализации...

Касательно ANALYTIC...LISTAGG...WITHIN нет уверенности что они работают эквивалентно...начальному исходному коду...
Volod
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеВт Июл 17, 2018 15:36    Ответить с цитатой
Полезность: 1
case возвращает одну сущность - в колонках же case именно так функционирует?
vtar
Эксперт


Вступление в Клуб: 20.03.2009
СообщениеВт Июл 17, 2018 15:39    Ответить с цитатой
Полезность: 1
по ходу CASE однострочный , если в нем внутри многострочный select он взрывается

тогда нужно как то к одной строке сворачиваться в CASE и понятно почему distinct не сработал - он дубли убирает а не сворачивает , совет был плохой Smile
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеВт Июл 17, 2018 15:55    Ответить с цитатой
Полезность: Нет оценки
Тогда вполне всё логично...

хотя в описании как то размыто написано

case-выражения, позволяющие использовать логическое ветвление (аналогично оператору выбора, см. пункт Оператор выбора).
case
when < условие 1 > then < результирующее выражение 1 >
[ when < условие 2 > then < результирующее выражение 2 > ]
[ ... ]
[ else < результирующее выражение > ]
end
При этом если выполняется условие в одной из ветвей when, то результатом будет
соответствующее < результирующее выражение i > после then, если ни одно из условий when не
выполняется и присутствует ветвь else, тогда возвращается < результирующее выражение >
после else, иначе возвращается пустое значение (возвращаемые значения во всех ветвях должны
быть однотипны).

< результирующее выражение i > .... возвращаемые значения во всех ветвях должны быть однотипны...

однотипны ... видимо здесь имеется в виду одиночные значения любого типа... не массив

сенкс


получается что для задачи корректно

select sum() in
[
select count()
where фильтр - соответствующая часть 1ого CASE
union all
select count()
where фильтр - соответствующая часть 1ого CASE
union all
select count()
where фильтр - соответствующая часть 2ого CASE
union all
select count()
where фильтр - соответствующая часть 2ого CASE
]
into cnt

(case таки не подходит)
Матвеев Евгений
Профи


Вступление в Клуб: 31.01.2012
СообщениеВс Июл 22, 2018 14:50    Ответить с цитатой
Полезность: Нет оценки
vtar пишет:
по ходу CASE однострочный , если в нем внутри многострочный select он взрывается

тогда нужно как то к одной строке сворачиваться в CASE и понятно почему distinct не сработал - он дубли убирает а не сворачивает , совет был плохой Smile


И еще пару моментов... vtar...

select x(count(x) :c ) in ::[AC_FIN] all
where x.[CLIENT_V] in (case
when class_ in ('CL_ORG')
then (p_client)
when class_ in ('CL_PRIV')
then
( select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
end)
and x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')

union all

select x(count(x) : c) in ::[AC_FIN] all
where x.[CLIENT_V] in (case
when class_ in ('CL_ORG')
then (p_client)
when class_ in ('CL_PRIV')
then
( select w(w.[PARTNER])
in ::[LINKS_CL]
,(::[CL_ORG] all: org) all
where w%collection = p_client.[LINKS_OTHER]
and w.[PARTNER] = org
)
end)
and x.[COM_STATUS] is null


сравнил тексты, у них различие только в одной строке

and x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')

and x.[COM_STATUS] is null

Может реализовать так?

and
(
(
x.[COM_STATUS] != ::[COM_STATUS_PRD]([CODE]='TO_OPEN')
)
or
(
x.[COM_STATUS] is null
)
)

без union

это первый момент

второй момент, ... для второй части Union all возможно имелось в виду

не where x.[CLIENT_V] in (case
a where x.[CLIENT_R] in (case
???
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle Часовой пояс: GMT + 3
На страницу 1, 2  След.
Страница 1 из 2

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru