oracle函数之case和decode的用法区别及性能比较

标签: oracle 函数 case | 发表时间:2012-08-01 22:09 | 作者:手心上的冰山
出处:http://www.blogjava.net/

   在oracle世界,你可以使用:

    1)case表达式      或者

    2)decode函数

    来实现逻辑判断。Oracle的DECODE函数功能很强,灵活运用的话可以避免多次扫描,从而提高查询的性能。而CASE是9i以后提供的语法,这个语法更加的灵活,提供了IF THEN ELSE的功能。   

    case表达式

    case表达式,可分两种,简单和搜索,简单case后接表达式,如:

    对于简单的case需要几点注意:

    1)寻找when的优先级:从上到下

    2)再多的when,也只有一个出口,即其中有一个满足了expr就马上退出case

    3)不能把return_expr和else_expr指定为null,而且,expr、comparison_expr和return_expr的数据类型必须相同。

    搜索case:

    CASE WHEN condition THEN return_expr

              [WHEN condition THEN return_expr]

              ...

    ELSE else_expr

    END

    例子:

[sql]  view plain copy
  1. SELECT (CASE WHEN cust_credit_limit BETWEEN  0 AND 3999 THEN  ' 0 - 3999'  
  2.    WHEN cust_credit_limit BETWEEN  4000 AND 7999 THEN ' 4000 - 7999'  
  3.    WHEN cust_credit_limit BETWEEN  8000 AND 11999 THEN  ' 8000 - 11999'  
  4.    WHEN cust_credit_limit BETWEEN  12000 AND 16000 THEN '12000 - 16000' END)  
  5.   AS BUCKET, COUNT(*) AS Count_in_Group  
  6. FROM customers WHERE cust_city = 'Marshal' GROUP BY  
  7.  (CASE WHEN cust_credit_limit BETWEEN  0 AND 3999 THEN ' 0 - 3999'  
  8.  WHEN cust_credit_limit BETWEEN  4000 AND 7999 THEN ' 4000 - 7999'  
  9.  WHEN cust_credit_limit BETWEEN  8000 AND 11999 THEN  ' 8000 - 11999'  
  10.  WHEN cust_credit_limit BETWEEN  12000 AND 16000 THEN '12000 - 16000' END);  
  11.   
  12. BUCKET        COUNT_IN_GROUP  
  13. ------------- --------------  
  14.  0 - 3999                  8  
  15.  4000 - 7999               7  
  16.  8000 - 11999              7  
  17. 12000 - 16000              1  

    用decode可以违反第3NF(行不可再分,列不可再分,列不可重复):列重复

[sql]  view plain copy
  1. hr@ORCL> select * from a;  
  2.   
  3.         ID NAME  
  4. ---------- ----------  
  5.          1 a  
  6.          2 b  
  7.          3 c  
  8.          1 a  
  9.   
  10. hr@ORCL> select sum(decode(id,1,1,0)) think,  
  11.   2             sum(decode(id,2,2,0)) water,  
  12.   3             sum(decode(id,3,3,0)) linshuibin  
  13.   4        from a;  
  14.   
  15.      THINK      WATER LINSHUIBIN  
  16. ---------- ---------- ----------  
  17.          2          2          3  

 

    一个字段,decode函数可以完全改写简单case;

    多个字段,需要复杂的case,方可。

    语法:
    DECODE(value,if1,then1,if2,then2,if3,then3,...,else),表示如果value等于if1时,DECODE函数的结果返then1,...,如果不等于任何一个if值,则返回else。可以用函数或表达式来替代value,if,then,else从而作出一些更有用的比较。

    来看看具体的运用:
    1 假设我们想给百度职员加工资,其标准是:工资在8000元以下的将加20%;工资在8000元以上的加15%
    则:

    select decode(sign(salary - 8000),1,salary*1.15,-1,salary*1.2,salary) "revised_salary" from employee

    2 表table_subject,有subject_name列。要求按照:语、数、外的顺序进行排序
    则:

    select * from table_subject order by decode(subject_name, '语文', 1, '数学', 2, , '外语',3)

    decode和简单case的性能比较

 

   

Oracle的DECODE函数功能很强,灵活运用的话可以避免多次扫描,从而提高查询的性能。而CASE是9i以后提供的语法,这个语法更加的灵活,提供了IF THEN ELSE的功能。


对于很多情况,DECODE和CASE都能解决问题,个人更倾向于使用DECODE,一方面是从8i保留下来的习惯,另一方面是DECODE的语法更加的简洁,代码量要小一些。

不过今天在看Oracle9i的数据仓库手册时发现,Oracle在文档中提到CASE语句的效率会更高一些,尤其是CASE表达式 WHEN 常量 THEN的语法,效率要比CASE WHEN表达式 THEN的语法更高一些。对于后面这种说法倒是没有太多的疑问,对于CASE比DECODE效率高这种说法倒是第一次看到,印象中DECODE效率很高,应该不会比CASE的效率差。

到底效率如何,还是要具体的实例来说:

SQL> CREATE TABLE T AS
2 SELECT A.*
3 FROM DBA_OBJECTS A, DBA_MVIEWS;

Table created.

SQL> SELECT COUNT(*) FROM T;

COUNT(*)
----------
6075760

下面检查DECODE和两种CASE语句的效率:

SQL> SET ARRAY 1000
SQL> SET TIMING ON
SQL> SET AUTOT TRACE 
SQL> SELECT DECODE(OWNER, 'SYSTEM', 'SYSTEM', 'SYS', 'SYSTEM', 'USER') 
2 FROM T;

6075760 rows selected.

Elapsed: 00:00:07.24

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4245K| 68M| 13828 (1)| 00:03:14 |
| 1 | TABLE ACCESS FULL| T | 4245K| 68M| 13828 (1)| 00:03:14 |
--------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement


Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
47551 consistent gets
0 physical reads
0 redo size
46288564 bytes sent via SQL*Net to client
67317 bytes received via SQL*Net from client
6077 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6075760 rows processed

SQL> SELECT CASE OWNER WHEN 'SYSTEM' THEN 'SYSTEM'
2 WHEN 'SYS' THEN 'SYSTEM' 
3 ELSE 'USER' END 
4 FROM T;

6075760 rows selected.

Elapsed: 00:00:07.22

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4245K| 68M| 13828 (1)| 00:03:14 |
| 1 | TABLE ACCESS FULL| T | 4245K| 68M| 13828 (1)| 00:03:14 |
--------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement


Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
47551 consistent gets
0 physical reads
0 redo size
46288578 bytes sent via SQL*Net to client
67317 bytes received via SQL*Net from client
6077 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6075760 rows processed

SQL> SELECT CASE WHEN OWNER = 'SYSTEM' THEN 'SYSTEM'
2 WHEN OWNER = 'SYS' THEN 'SYSTEM' 
3 ELSE 'USER' END 
4 FROM T;

6075760 rows selected.

Elapsed: 00:00:07.23

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4245K| 68M| 13828 (1)| 00:03:14 |
| 1 | TABLE ACCESS FULL| T | 4245K| 68M| 13828 (1)| 00:03:14 |
--------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement


Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
47551 consistent gets
0 physical reads
0 redo size
46288585 bytes sent via SQL*Net to client
67317 bytes received via SQL*Net from client
6077 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6075760 rows processed



相关 [oracle 函数 case] 推荐:

oracle函数之case和decode的用法区别及性能比较

- - BlogJava-首页技术区
   在oracle世界,你可以使用:.     1)case表达式      或者.     2)decode函数. Oracle的DECODE函数功能很强,灵活运用的话可以避免多次扫描,从而提高查询的性能. 而CASE是9i以后提供的语法,这个语法更加的灵活,提供了IF THEN ELSE的功能.

Oracle CASE WHEN 用法介绍

- - CSDN博客推荐文章
Oracle CASE WHEN 用法介绍. CASE WHEN 表达式有两种形式. CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END. CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END.

一个InnoDB性能超过Oracle的调优Case

- - P.Linux Laboratory
年前抽空到兄弟公司支援了一下Oracle迁移MySQL的测试,本想把MySQL调优到接近Oracle的性能即可,但经过 @何_登成 @淘宝丁奇 @淘宝褚霸 @淘伯松 诸位大牛的指导和帮助(排名不分先后,仅按第一次为此CASE而骚扰的时间排序),不断修正方案,最终获得了比Oracle更好的性能,虽然是个特殊场景,但是我觉得意义是很广泛的,值得参考,遂记录于此.

Oracle函数介绍

- - CSDN博客数据库推荐文章
在SQL中有两种函数一种是单行函数,一种是多行函数.在sql与pl/sql中都自带了很多类型的函数,比如有字符、数字、日期、转换和混合型等多种函数用于处理单行数据,因此这些都被称为单行函数.这些函数都可以被用于select、where和oder by等子句中.下面我们就来分析单行函数,在这里我列举了oracle中一些常用的单行函数进行操作.希望你所有收获:.

Oracle数据库分析函数详解

- - MySQLOPS 数据库与运维自动化技术分享
Oracle数据库分析函数详解. 原创文章,转载请注明: 文章地址 Oracle数据库分析函数详解.

一个GC频繁的Case

- loudly - BlueDavy之技术Blog
前两天碰到一个很诡异的GC频繁的现象,走了不少弯路,N种方法查找后才终于查明原因了,在这篇blog中记录下,以便以后碰到这类问题时能更快的解决. 前两天一位同学找到我,说有个应用在启动后就一直Full GC,拿到GC log先看了下,确实是非常的诡异,截取的部分log如下:. 这个日志中诡异的地方在于每次Full GC的时候旧生代都还有很多的空间,于是去看来下启动参数,此时的启动参数如下:.

烤鱼铅笔袋:Grilled Fish Pencil Case

- Robert - 爱…稀奇~{新鲜:科技:创意:有趣}
这是各种烧烤和夜啤酒爱好者的最佳装备:烤鱼铅笔袋(Grilled Fish Pencil Case),当然也可以当手袋用,放点文具、尺子或者最爱的化妆品甚至是套套,都能彪悍得炭烧味四射,由不得周围人侧目而视~2480日元一个,从内文中的细部图来看,做工相当不错的说. 亲爱的,这些东西也会对你胃口:.

i-Camera Case 超逼真立体相机iPhone壳

- 电饭锅 - 设计|生活|发现新鲜
超有趣仿真相机iPhone4外壳到货啦,超精致细节,迄今最逼真的立体效果,绝对萌翻天. 高仿真设计,镜头部可以调节,拉出后可以作为支架斜立于桌面. 黑白、白色、粉色、绿色四色可选,点此购买. 颜色:黑色,白色,粉色,绿色. 规格:W12.3cm x D3cm x H6.7cm. 「设计,生活,发现新鲜」在新浪微博,更即时地获读更新,更直接地交流沟通.

「拍!搞定!」Graft Concepts 推出为 iPhone 4 而设的 Leverage Case

- Mr.aa - Engadget 中国版
相信 iPhone 4 的用户们都不会对 Blade Element 和 Deff Cleave 等金属制的 Bumper 感到陌生;但它们都有一个通病,就是在套上手机的过程中要上好几颗螺丝,很不方便呢. 不过 Graft Concepts 为 iPhone 4 而设的 Leverage Case 就不同了,因为它在套上 iPhone 后只要「拍」一声扣上右上角的金属机关便能套紧手机.

深入JVM彻底剖析前面ygc越来越慢的case

- - HelloJava微信公众账号网站
阿里JVM团队的同学帮助从JVM层面继续深入的剖析了下前面那个ygc越来越慢的case,分析文章相当的赞,思路清晰,工具熟练,JVM代码熟练,请看这位同学(阿里JVM团队:寒泉子)写的文章,我转载到这. 虽然这个demo代码逻辑很简单,但是其实这是一个特殊的demo,并不简单,如果我们将XStream对象换成Object对象,会发现不存在这个问题,既然如此那有必要进去看看这个XStream的构造函数(请大家直接翻XStream的代码,这里就不贴了).