具有长解码/案例的 Oracle 函数

发布于 2024-09-26 03:19:16 字数 1778 浏览 4 评论 0原文

我还有一个简单的。如何在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;

这样我就可以有一个清晰的查询,只使用这个函数到组中,并以我喜欢的方式进行一切:)

问题是我不能在 ([来自 query3 的 ids 的长列表])< 中使用 id_in /code> 在 switch 情况下,我在 plsql 方面非常熟练...

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

谢谢!

f.

I have another simple one. How to make a long decode inside a function in oracle?

My select looks like this:

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

And I have a couple more of large code lists like that which I want to turn into one neat query.

Something like:

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;

so I can have a clear query that just uses this function into the group by and everything the way I like :)

The problem is I cant use that id_in in ([long list of ids from query3]) in the switch cases and I'm quite a n00b in plsql...

May I get suggestions of elegant ways of doing it?

thanks!

f.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初与友歌 2024-10-03 03:19:16

这是一个可能的解决方案:创建 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

Here is a possible solution: create 2 tables :

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)
);

This way you only need to join the tables, no CASE or DECODE needed

The final query would look something like that :

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

实际上,您第一次尝试的唯一问题是您混淆了 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;

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

Actually, the only problem with your first stab is that you've mixed up the two syntaxes of the CASE expression.

If you follow the CASE keyword with an expression (e.g. id_in), then you are doing a switch on the value of that expression, and each of the WHEN clauses must include a single expression that will be checked for equality against the first expression.

Alternatively, you can skip the expression immediately after CASE, and specify a full boolean condition in each WHEN clause.

So, either of these should work for you:

   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;

Note that overall, I agree with others that the preferable way to do this is store the mapping of ID values to groups in another table and change the query to a join.

如歌彻婉言 2024-10-03 03:19:16

只需确保您的长 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;

我猜这不是最亮的东西,但可以满足你的功能。是的,最好将这些代码存储在一个单独的表中,您确实可以将其加入查询中。

Just make sure your long lists of ids do not intersect.

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;

Not the brightest thing, I guess, but will work for your function. And, yes, it's better to store these codes in a separate table you could join into your query, indeed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文