我有另一个简单的。如何在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])
而且我在plsql中非常使用n00b ...
我可以获得优雅方法的建议吗?
谢谢!
F。
答案 0 :(得分:2)
这是一个可能的解决方案:创建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 :(得分:1)
实际上,第一次尝试的唯一问题是你混淆了CASE表达式的两种语法。
如果您使用表达式(例如id_in
)跟随CASE关键字,那么您正在切换该表达式的值,并且每个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值映射到另一个表中的组,并将查询更改为连接。
答案 2 :(得分:0)
请确保您的长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;
我猜这不是最亮的东西,但会对你的功能起作用。并且,是的,最好将这些代码存储在您可以加入查询的单独表中。