Sql 具有长解码/案例的Oracle功能

Sql 具有长解码/案例的Oracle功能,sql,oracle,plsql,Sql,Oracle,Plsql,我还有一个简单的。如何在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','47

我还有一个简单的。如何在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;
因此,我可以有一个清晰的查询,只需以我喜欢的方式将此函数用于group by和所有内容:)

问题是我不能在切换情况下使用([query3的长id列表])中的
id\u
,我在plsql中是一个n00b

我可以得到一些优雅的方法吗

谢谢


f、 这里有一个可能的解决方案:创建两个表:

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

下面是一个可能的解决方案:创建两个表:

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

只需确保您的长ID列表不相交即可

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;

我想这不是最聪明的事情,但会对你的功能起作用。是的,最好将这些代码存储在一个单独的表中,您可以将其加入到查询中。

只需确保您的长ID列表不相交即可

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;

我想这不是最聪明的事情,但会对你的功能起作用。是的,最好将这些代码存储在一个单独的表中,您可以将其加入到查询中。

事实上,第一次尝试的唯一问题是您混淆了CASE表达式的两个语法

如果在CASE关键字后面跟一个表达式(例如,中的
id\u),则您正在对该表达式的值进行切换,并且每个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;

请注意,总的来说,我同意其他人的看法,最好的方法是将ID值映射到另一个表中的组,并将查询更改为联接。

实际上,第一次尝试的唯一问题是混淆了CASE表达式的两个语法

如果在CASE关键字后面跟一个表达式(例如,
中的
id\u),则您正在对该表达式的值进行切换,并且每个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;

注意到,总体上,我同意其他人的观点,最好的办法是将ID值映射到另一个表中的组,并将查询更改为联接。

您可以考虑将“长列表”放入自己的表中,使其变得更简单。事实上,我有一些其他的功能。尽管如此,数据是非常静态的,没有那么多数据。。我想知道我是否能在函数本身中实现它。如果你能在纯SQL中实现它,你应该这样做,只有当你看到你不能在SQL中实现它时,你才应该使用PLSQL。。像您尝试过的那样使用标量函数时会有一点开销,而且对于其他接管您的代码的人来说可能不太容易阅读。这里的开销不是问题。我的意思是,我有一个函数,我可以使用它查找表来执行解码,它工作得很好。我只是在寻找一个优雅的方式来做它而不需要额外的表格…如果你不介意使用一个带有状态的包,你可以使用一个关联数组(填充在包初始化中)将ID映射到一个组。你可以考虑把这个“长列表”放在它自己的表中以使它变得简单。事实上,我有一些其他的功能。尽管如此,数据是非常静态的,没有那么多数据。。我想知道我是否能在函数本身中实现它。如果你能在纯SQL中实现它,你应该这样做,只有当你看到你不能在SQL中实现它时,你才应该使用PLSQL。。像您尝试过的那样使用标量函数时会有一点开销,而且对于其他接管您的代码的人来说可能不太容易阅读。这里的开销不是问题。我的意思是,我有一个函数,我可以使用它查找表来执行解码,它工作得很好。我只是在寻找一种不需要额外表的优雅方法…如果您不介意使用带状态的包,您可以使用关联数组(在包初始化时填充)将Id映射到组。谢谢。。。但是不能做:(说来话长,但我不能碰将要进行的实际连接。)(谢谢…但是不能做:(说来话长,但我不能碰将要进行的实际连接。)(酷..做到了(尽管我最终创建了一个表)酷..做到了(尽管我最终创建了一个表)