Oracle работает с длинными декодировками - PullRequest
0 голосов
/ 05 октября 2010

У меня есть еще один простой.Как сделать длинное декодирование внутри функции в oracle?

Мой выбор выглядит так:

select something, sum(ofsomethingelse)
from a_table
where code in 
('390','391','392','393','394','395','396','397','398','400','402','406',
'407','408','409','410','411','412','413','414','416','418','471','473',
'1734','1742','1735','1736','1737','1738','1739','1740','1741','1745',
'1748','1752','1760','1753','1754','1755','1756','1757','1758','1759',
'1763','1766','1902','1904','1003','1011','1004','1005','106','1007',
'1008','1009','1010','1159','1161','1015','1023','1016','1017','1018',
'1019','1020','1021','1022','1164','1166','1189','1191','1201','1209',
'1202','1203','1204','205','1206','1207','1208','1356','1358','1213',
'1221','1214','1215','1216','1217','1218','1219','1220','1361','1363',
'1386','1388','1401','1409','1402','1403','1404','1405','1406','1407',
'1408','1557','1559','1413','1421','1414','1415','1416','1417','1418',
'1419','1420','1562','1564','1587','1589','9033','9034','9035','9036',
'9037','9038','909','9040','9049','9050','9051','9052')
group by something
order by 1

И у меня есть еще пара больших списков кодов, которые я хочу включитьв один аккуратный запрос.

Что-то вроде:

CREATE OR REPLACE FUNCTION grouping_func (id_in IN varchar2)
RETURN varchar2
AS
res varchar(255);
BEGIN
   res := CASE id_in
            WHEN id_in in ([long list of ids from query1]) THEN 'Group1'
            WHEN id_in in ([long list of ids from query2]) THEN 'Group2'
            WHEN id_in in ([long list of ids from query3]) THEN 'Group3'
            ELSE id_in
          END;
    RETURN res;
END;

, поэтому у меня может быть четкий запрос, который просто использует эту функцию в группу и все, как мне нравится:)

Проблема в том, что я не могу использовать это id_in in ([long list of ids from query3]) в коммутаторах, и я просто n00b в plsql ...

Могу ли я получить предложения об элегантных способах сделать это?

спасибо!

ф.

Ответы [ 3 ]

2 голосов
/ 05 октября 2010

Вот возможное решение: создайте 2 таблицы:

create table GROUPS 
(
GRP_ID INTEGER,
GRP_NAME VARCHAR2(20) // name of the group
);

create table LONGLIST
(
LL_ID INTEGER,
LL_NAME  VARCHAR2(20) // item of your big list
GRP_ID INTEGER // (foreign key)
);

Таким образом, вам нужно только объединить таблицы, не требуя CASE или DECODE

Окончательный запрос будет выглядеть примерночто:

select g.grp_name, sum(ofsomethingelse)
from a_table a
inner join longlist ll on ll.ll_name = a.code
inner join groups g on g.grp_id = ll.grp_id
group by g.grp_name
1 голос
/ 06 октября 2010

На самом деле единственная проблема с вашим первым ударом состоит в том, что вы перепутали два синтаксиса выражения CASE.

Если после ключевого слова CASE используется выражение (например, id_in), товы переключаете значение этого выражения, и каждое из предложений WHEN должно включать одно выражение, которое будет проверяться на равенство с первым выражением.

В качестве альтернативы, вы можете пропустить выражение сразу после CASEи укажите полное логическое условие в каждом предложении WHEN.

Итак, любой из них должен работать для вас:

   res := CASE id_in
         WHEN 390 THEN 'Group1'
         WHEN 391 THEN 'Group1'
         WHEN 392 THEN 'Group2'
         ...etc...

   res := CASE
            WHEN id_in in ([long list of ids from query1]) THEN 'Group1'
            WHEN id_in in ([long list of ids from query2]) THEN 'Group2'
            WHEN id_in in ([long list of ids from query3]) THEN 'Group3'
            ELSE id_in
          END;

Обратите внимание, что в целом я согласен с другими, что предпочтительный способДля этого сохраните сопоставление значений идентификаторов группам в другой таблице и измените запрос на объединение.

0 голосов
/ 05 октября 2010

Просто убедитесь, что ваши длинные списки идентификаторов не пересекаются.

CREATE OR REPLACE FUNCTION grouping_func(id_in IN varchar2) RETURN varchar2 AS
  res varchar2(255);
BEGIN
  select gr
    into retval
    from (select 'Group1' gr
            from dual
           where id_in in ('[long list of ids from query1]')
          union all
          select 'Group2' gr
            from dual
           where id_in in ('[long list of ids from query2]')
          union all
          select 'Group3' gr
            from dual
           where id_in in ('[long list of ids from query3]'));

  exception 
    when no_data_found then
     return null;
    when too_many_rows then
     return null;    
END;

Не самая яркая вещь, я думаю, но будет работать для вашей функции. И да, лучше хранить эти коды в отдельной таблице, которую вы действительно можете включить в свой запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...