Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Матвеев Евгений Профи
Вступление в Клуб: 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 не сработал - он дубли убирает а не сворачивает , совет был плохой  |
|
 |
Матвеев Евгений Профи
Вступление в Клуб: 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 не сработал - он дубли убирает а не сворачивает , совет был плохой  |
И еще пару моментов... 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
??? |
|
 |
|