[数据库基础]Oracle查询优化改写_03

从今天开始,我跟大家一起学习Oracle的基础知识。孔子曰:“温故而知新,可以为师矣”。学过的东西,也要经常回顾一下,才能记得更牢,用的更溜。
1. 按数字和字母混合字符串中的字母排序

create or replace view v
as
select empno || ' ' || ename as data from emp;

这里写图片描述
需求:按照视图v里字段中的ename的值排序。
那么问题来了,怎么把ename从字符串中剔除出来呢?因为ename出来以后排序是很简单的。
我们选择使用translate函数,语法还记得吗?不记得的再来温习一下。
translate(expr,from_string,to_string)

select v.data, translate(v.data, '0123456789 a', 'a') b 
from v 
order by b;

这里写图片描述
大功告成!
Tips:如果to_string为空,那返回为空。
SELECT TRANSLATE(‘12你好454658342’, ‘-1234567890’, ”) AS DATA FROM DUAL;

如果to_string对应的位置没有字符,那么from_string中的字符就会被消掉。
SELECT TRANSLATE(‘12你好454658342’, ‘-1234567890’, ‘-‘) AS DATA FROM DUAL;


我们来看第二个问题
2.处理排序空值
我们可能处理空值时,习惯将空值用-1代替,然后再排序。

法1:
SELECT T.ENAME, T.SAL, T.COMM, NVL(T.COMM, -1) FROM EMP T ORDER BY 4;
法2:
SELECT T.ENAME, T.SAL, T.COMM FROM EMP T ORDER BY 3 NULLS FIRST;

方法一是常用的写法,方法二是使用了函数去实现的是不是简单很多。因为第一种方法需要对列类型及其中保存的数据有所了解才行,而且保存的数据如果有变化,该语句就需要重新维护。
使用NULLS FIRST和NULLS LAST就会很方便。


3.根据条件取不同列中的值来排序
有时候排序的要求比较复杂,比如:领导对工资在1000到2000元之间的员工更感兴趣,于是要求工资在这个范围的员工要排在前面,以便优先查看。
针对这种需求,我们可以在查询中的新生成一列,有多列排序的方法实现。

SELECT  T.ENAME, 
    T.SAL,
    T.COMM,
    CASE 
      WHEN T.SAL >= 1000 AND T.SAL <2000 THEN 1
      ELSE 2 
    END AS ROW_ID
FROM EMP T
ORDER BY 4, 2;

这里写图片描述
4.查看sql的执行计划的方法

--先执行一条语句,之后查看更新后的执行计划。
EXPLAIN PLAN FOR 
SELECT T.ENAME, T.SAL,T.COMM,CASE WHEN T.SAL >= 1000 AND T.SAL <2000 THEN 1
ELSE 2 END AS ROW_ID
FROM EMP T
ORDER BY 4, 2;
COMMIT;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

5.合集(union) 和 并集(union all)的区别

--法一
SELECT * FROM EMP T WHERE T.EMPNO = 7788 OR T.ENAME = 'SCOTT'; 

--法二
SELECT * FROM EMP T WHERE T.EMPNO = 7788
UNION ALL
SELECT * FROM EMP T WHERE T.ENAME = 'SCOTT';

--法三
SELECT * FROM EMP T WHERE T.EMPNO = 7788
UNION
SELECT * FROM EMP T WHERE T.ENAME = 'SCOTT';

合集等价于关系运算符OR,不等于并集。
合集union的作用:
1.不仅两个数据集合间重复的数据会被去重,而且单个数据集里重复的数据也会被去重。
2.有重复数据的数据集用union后得到的数据与预期不一致。
所以在使用union时,要确保在去重前加一个可以唯一标识各行的列即可。
这个唯一标识的行可以是唯一列、主键列,还可以是rowid。
但如果数据取自视图,没有rowid时 ,就需要增加一列rownum来当做唯一列。
举个栗子:

WITH E AS
 (SELECT ROWNUM AS SN, V.DEPTNO, V.MGR, V.JOB FROM V)
SELECT DEPTNO
  FROM (SELECT * FROM E WHERE MGR = 7698
        UNION
        SELECT * FROM E WHERE JOB = 'SALESMAN')
 ORDER BY 1;

这里的WITH语句,可以理解为临时创建的在查询期间存在的的VIEW(e)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值