decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值2,否则返回值3
当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多
该函数的含义如下:
IF 条件=值1 THEN
RETURN(返回值1)
ELSIF 条件=值2 THEN
RETURN(返回值2)
......
ELSIF 条件=值n THEN
RETURN(返回值n)
ELSE
RETURN(缺省值)
END IF
DECODE函数的常见用途:按字段内容分组、按字段内容排序、固定行转列
1. 使用DECODE实现按字段内容分组
有时候分组可能比较复杂,比如需要对某些字段内容合并分组处理,这样使用简单的GROUP BY 就不行了,
但是使用CASE或DECODE就可以得到预期的结果
范例:
- 建立简单的雇员及对应职位表
DROP TABLE t1;
CREATE TABLE t1
(
ID NUMBER(10),
NAME VARCHAR2(10),249);">JOB VARCHAR2(20)
);
INSERT INTO t1 VALUES(1,'jack','VP');
INSERT INTO t1 VALUES(2,'tony','CEO');
INSERT INTO t1 VALUES(3,'merry',249);">INSERT INTO t1 VALUES(4,'james','OPERATION');
INSERT INTO t1 VALUES(5,'linda',249);">COMMIT;
现在需要分别统计VP及以上职位的人数、普通雇员的人数,这是使用简单的GROUP BY JOB
是不行的,使用DECODE来实现就很简单
SELECT DECODE(JOB,'VP','VP_CEO','CEO','OPERATION') JOB,249);">COUNT(*) JOB_CNT
FROM t1
GROUP BY DECODE(JOB,249);">
结果如下:
JOB JOB_CNT
----------- --------------
VP_CEO 3
OPERATION 2
2. 使用DECODE实现按字段内容排序
在日常开发中可能碰到这样的情况,比如一张表有ID,NAME字段(ID为代理主键),
需要按NAME值指定排序规则(如NAME是字符型'某某部分'),那么怎样实现排序呢?
- 建立测试表
DROP TABLE t2;
CREATE TABLE t2
ID NUMBER,249);">DEPT_NAME VARCHAR2(10),249);">REGION_ID NUMBER(10)
INSERT INTO t2 VALUES(1,'deptA',12);
INSERT INTO t2 VALUES(2,10);
INSERT INTO t2 VALUES(3,9);
INSERT INTO t2 VALUES(4,7);
INSERT INTO t2 VALUES(5,'deptB',249);">INSERT INTO t2 VALUES(6,13);
INSERT INTO t2 VALUES(7,22);
INSERT INTO t2 VALUES(8,249);">INSERT INTO t2 VALUES(9,'deptC',8);
INSERT INTO t2 VALUES(10,249);">INSERT INTO t2 VALUES(11,11);
- a. 按字段内容排序
需求:按部门DEPT_NAME排序(A->B->C),对于每个部门内部按区域REGION_ID升序
分析:这里的部门DEPT_NAME不是数字(varchar2),直接排序时不行的,
如果能将DEPT_NAME的每个值转为对应的数字,再排序就可以了。
SELECT ID,DEPT_NAME,REGION_ID
FROM t2
ORDER BY DECODE(DEPT_NAME,249);">'deptA',1,249);">'deptb',2,249);">3),249);">REGION_ID;
- b. 按字段内容指定动态列排序
需求:若DEPT_NAME为deptA,则按ID升序排列,否则按REGION_ID升序排序
REGION_ID);
3. 使用DECODE实现固定行转列
- 简单的员工工作统计表
DROP TABLE t3;
CREATE TABLE t3
STUDENT_NO NUMBER(10),249);">STUDENT_NAME VARCHAR2(10),249);">COURSE_TYPE VARCHAR2(10),249);">COURSE_score NUMBER(10)
INSERT INTO t3 VALUES(1,'english',80);
INSERT INTO t3 VALUES(2,70);
实现行转列:
SELECT STUDENT_NAME,DECODE(COURSE_TYPE,COURSE_score) FROM t3;
分析这条语句,分组与不分组的差别在哪里?
MAX(DECODE(COURSE_TYPE,COURSE_score)) ENGLISH,COURSE_score)) CHINESE,COURSE_score)) MATH
FROM t3
GROUP BY STUDENT_NAME;
为什么需要MAX?
因为要实现行转列,按字段分组,对DECODE中的非分组列必须要有分组函数,当然MIN、SUM
AVG等组函数也可以实现,MAX、MIN对任何类型都适用,SUM、AVG只能对数