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

LEFT JOIN в PL+

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle
Предыдущая тема :: Следующая тема  
Автор Сообщение
Blinderbor
Участник


Вступление в Клуб: 18.12.2012
СообщениеСр Дек 26, 2012 08:43   LEFT JOIN в PL+ Ответить с цитатой
Полезность: Нет оценки
Задача: вывести из ТБП [конверсионные операции] все департаменты для операций на определенную дату и категорию клиента на этот момент. Если категории нет, то департамент все равно выводить (left join)

добавляю (true) что бы получить left join
Код:
 
         select s(
              s.[DEPART].[NAME] c_dep
              ,NVL(s.[CLIENT].[VIDS_CL].[CATEGORY].[kODE], 'no_cat_beznal') c_clnt_cat
             )
              in ::[SALE]
              where  trunc(s.[INPUT].[DATE_VALUE])>trunc(s.[CLIENT].[VIDS_CL].[DATE_BEGIN](true))


код компилируется, в пакете то что надо
Код:
a4.C_VIDS_CL=a5.collection_id(+)

Код:
select  a3.C_NAME C_DEP, NVL(a6.C_CODE,'no_cat_beznal') C_CLNT_CAT
from Z#CL_GROUP a6, Z#CL_CATEGORIES a5, Z#CLIENT a4, Z#DEPART a3, Z#PRODUCT a2, Z#SALE a1
where a1.id=a2.id and a2.C_DEPART=a3.id(+) and a1.C_CLIENT=a4.id and a4.C_VIDS_CL=a5.collection_id(+) and a5.C_CATEGORY=a6.id(+)
  and (TRUNC(a1.C_INPUT#DATE_VALUE) > TRUNC(a5.C_DATE_BEGIN(+)));



при выполнении операции выдает сообщение
Цитата:
таблица может быть экстра-соединена, чаще всего, с одной другой таблицей

и все, данные не выдает ((

прошу подсказать где я не прав


Последний раз редактировалось: Blinderbor (Ср Дек 26, 2012 10:19), всего редактировалось 1 раз
devor
Профи


Вступление в Клуб: 13.02.2012
СообщениеСр Дек 26, 2012 09:34    Ответить с цитатой
Полезность: 1
Плохо понимаете тему коллекций.
надо делать так:
[code]
for ( select s(
s.[DEPART].[NAME] c_dep
,nvl(( select vc(vc.[CATEGORY].[code]) in s.[CLIENT].[VIDS_CL] where vc.[DATE_BEGIN]<trunc(s.[INPUT].[DATE_VALUE])+1 and rownum<=1)
, 'no_cat_beznal'
) c_clnt_cat
)
in ::[SALE] all
)
loop
null;-- тут код
end loop;
[/code]
Blinderbor
Участник


Вступление в Клуб: 18.12.2012
СообщениеСр Дек 26, 2012 09:50    Ответить с цитатой
Полезность: Нет оценки
сработало
devor
Профи


Вступление в Клуб: 13.02.2012
СообщениеСр Дек 26, 2012 10:47    Ответить с цитатой
Полезность: Нет оценки
Blinderbor пишет:
сработало

Надо только учесть, что если у клиента есть несколько категорий подходящих по дате - то выборка вернет только одну.
Если нужен настоящий left join (т.е. вернуть на каждую категорию отдельную запись) то запрос нужно переписать - джойнить SALE с селектом.
Blinderbor
Участник


Вступление в Клуб: 18.12.2012
СообщениеПн Янв 21, 2013 16:08    Ответить с цитатой
Полезность: Нет оценки
devor пишет:
Blinderbor пишет:
сработало

Если нужен настоящий left join (т.е. вернуть на каждую категорию отдельную запись) то запрос нужно переписать - джойнить SALE с селектом.



хорошая идея, но уже при таком коде пакет не компилируется
выдает pl\sql ошибку

Код:
for (
     select s(
              s.[DEPART].[NAME] c_dep
              ,vc.c_cat c_clnt_cat
             )
              in ::[SALE], (select vc(vc.[CATEGORY].[kode] c_cat) in s.[CLIENT].[VIDS_CL] )
     )
loop
...
end loop;


Код:
cursor c_obj is
select  a3.C_NAME C_DEP, b1.C_CAT C_CLNT_CAT
from Z#SALE a1, Z#PRODUCT a2, Z#DEPART a3, Z#COM_STATUS_PRD a4, Z#SALE_LIST a5, Z#TYPE_SALE a6, Z#CLIENT a7, (
   select  c2.C_CODE C_CAT
   from Z#CL_GROUP c2, Z#CL_CATEGORIES c1
   where c1.COLLECTION_ID=a7.C_VIDS_CL and c1.C_CATEGORY=c2.id(+)) b1
where


Цитата:
pl\sql: ora-00904 "A7.C_VIDS_CL": недопустимый идентификатор


вопрос получается уже sql'ый
с ходу не нашел примеров для подобного выражение
Код:
select from tab1,(select...where col1=tab1.col2)

может кто знает как быть, я пока подумаю еще %)
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеВт Янв 22, 2013 07:57    Ответить с цитатой
Полезность: Нет оценки
Blinderbor пишет:

хорошая идея, но уже при таком коде пакет не компилируется
выдает pl\sql ошибку

Код:
for (
     select s(
              s.[DEPART].[NAME] c_dep
              ,vc.c_cat c_clnt_cat
             )
              in ::[SALE], (select vc(vc.[CATEGORY].[kode] c_cat) in s.[CLIENT].[VIDS_CL] )
     )
loop
...
end loop;

Цитата:
pl\sql: ora-00904 "A7.C_VIDS_CL": недопустимый идентификатор

Логично, что возникает ошибка.
Откуда во втором запросе (он же не вложенный) возьмётся табличка A7.

попробуй такой код:
Код:

select s(s.[DEPART].[NAME] c_dep
              ,vc.[CATEGORY].[kode] c_cat
) in ::[SALE], (::[CL_CATEGORIES] all :vc), (::[CLIENT] all :cl) all
where vc%collection(true) = cl.[VIDS_CL]
and cl%id(true) = s.[CLIENT]


или такой:
Код:

select s(s.[DEPART].[NAME] c_dep
              ,vc.[c_cat] c_cat
) in ::[SALE], (select vc(vc.[CATEGORY].[kode] c_cat) in ::[CL_CATEGORIES], (::[CLIENT] all :cl) all
where vc%collection(true) = cl.[VIDS_CL] )
where cl%id(true) = s.[CLIENT]
Blinderbor
Участник


Вступление в Клуб: 18.12.2012
СообщениеВт Янв 22, 2013 11:13    Ответить с цитатой
Полезность: Нет оценки
Цитата:
попробуй такой код:

благодарю за помощь, везде прямо успеваешь )), но
я в последнем примере упрощенно написал
есть еще условие на дату
нужно выбирать ВСЕ действующие категории клиента на дату конверсионной операции в которой он участвует
в первом сообщении в теме есть пример!
Мне подсказали использовать подзапрос в селекте - я пока на этом и остановился, но так можно получать только rownum<=1
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеСр Янв 23, 2013 05:59    Ответить с цитатой
Полезность: 1
Blinderbor пишет:
Цитата:
попробуй такой код:

благодарю за помощь, везде прямо успеваешь )), но
я в последнем примере упрощенно написал
есть еще условие на дату
нужно выбирать ВСЕ действующие категории клиента на дату конверсионной операции в которой он участвует
в первом сообщении в теме есть пример!
Мне подсказали использовать подзапрос в селекте - я пока на этом и остановился, но так можно получать только rownum<=1


Есть недокументированная функция Oracle WM_CONCAT Smile

select wm_concat(id) from z#dummy where rownum < 10;
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеСр Янв 23, 2013 06:11    Ответить с цитатой
Полезность: 1
Blinderbor пишет:
есть еще условие на дату


Код:
         select distinct
            dep(   dep.[NAME]   :c_dep
               ,   nvl(cat.[CATEGORY].[ code], 'no_cat_beznal') c_clnt_cat
         ) in ::[DEPART], (::[SALE] :s), (::[CLIENT] :cl), (::[CL_CATEGORIES] all :cat)
         where   s.[DEPART]%id = dep%id
                 and   cl%id(true)   = s.[CLIENT]%id
                 and   cat%collection(true) = cl.[VIDS_CL]
                 and   trunc(s.[INPUT].[DATE_VALUE]) > nvl(trunc(cat.[DATE_BEGIN]), s.[INPUT].[DATE_VALUE]-1)
Blinderbor
Участник


Вступление в Клуб: 18.12.2012
СообщениеЧт Янв 24, 2013 12:40    Ответить с цитатой
Полезность: Нет оценки
Цитата:
Есть недокументированная функция Oracle WM_CONCAT

в дейвелопере получилось,
PL+, похоже, с ней не знаком
положил в голову

Код:
Код:
         select distinct
            dep(   dep.[NAME]   :c_dep
               ,   nvl(cat.[CATEGORY].[ kode], 'no_cat_beznal') c_clnt_cat
         ) in ::[DEPART], (::[SALE] :s), (::[CLIENT] :cl), (::[CL_CATEGORIES] all :cat)
         where   s.[DEPART]%id = dep%id
                 and   cl%id(true)   = s.[CLIENT]%id
                 and   cat%collection(true) = cl.[VIDS_CL]
                 and   trunc(s.[INPUT].[DATE_VALUE]) > nvl(trunc(cat.[DATE_BEGIN]), s.[INPUT].[DATE_VALUE]-1) 

я так пробовал, в этом случае NVL то что мне не хватало! Чего я сам то не догадался )
благодарствую, добрый человек!!!!
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle Часовой пояс: GMT + 3
Страница 1 из 1

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