字符函数

转大写

dual 是虚拟表,用于补全语法

select upper('yes') from dual;  --YES

转小写

select lower('YES') from dual;   --yes

数值函数

  • 四舍五入,保留两位小数
  • -2 表示对小数点前面两位四舍五入
select round(13.14624, 2) from dual; --13.15

直接截取

select trunc(13.14624, 2) from dual; --13.14

取余

select mod(10, 3) from dual;  --1

日期函数

sysdate:系统时间,可以与数字进行运算

当前时间 +1 天

select sysdate+1 from dual;

某天距离现在几个月

select mouths_between(sysdate, t.date) from tb_name t;

转换函数

日期转字符

fm 月份不加 0

24 24 小时制

select TO_CHAR(sysdate, 'fm yyyy-mm-dd hh24:mi:ss') from dual;

字符转日期

select TO_DATE(sysdate, 'fm yyyy-mm-dd hh24:mi:ss') from dual;

NVL

如果 t.anull,返回 0,否则返回 t.a

select nvl(t.a, 0) from tb_name t;

条件表达式

Oracle、MySQL 通用

等值选择

else 可省略

select t.a
    case t.b
        when 'A' then 'a'
        when 'B' then 'b'
        else 'c'
    end
from tb_name t

范围选择

else 可省略

select e.sal
    case
        when e.sal>5000 then '高收入'
        when e.sal>3000 then '中收入'
        else '低收入'
    end
from emp e

decode

select t.a,
    decode(t.b,
       'A', 'a',
       'B', 'b',
       'c') b
from tb_name t

Tip

这是 Oracle 特有的语法,为了代码可重用,建议用通用语法

聚合函数

可以把多行记录变成一个值

count

sum

max

min

avg

分组查询

分组查询中,出现在 group by 后面的原始列,才能出现在 select 后面;没有出现在 group by 后面的列,想在 select 后面,必须加上聚合函数。

select e.deptno, avg(e.sal)
from emp e
where e.sal>800
group by e.deptno
having avg(e.sal)>2000

where 和 having 的区别:

  • where 是过滤分组前的数据,having 是过滤分组后的数据

  • where 必须在 group by 之前,having 是在 group by 之后

  • 不能使用别名做条件

连接查询

等值连接

select *
from emp e,dept d
where e.deptno=d.deptno;

如果 d 表为空,则结果为空

内连接

select *
from emp e inner join dept d
on e.deptno=d.deptno;

Tip

等值连接与内连接的结果是相同的,推荐用等值连接,通俗易懂

左连接

select *
from emp e left join dept d
on e.deptno=d.deptno;

emp 的数据全部展示,如果 dept 没有与 emp 匹配的数据,则展示为 null

右连接

select *
from emp e right join dept d
on e.deptno=d.deptno;

dept 的数据全部展示,如果 emp 没有与 dept 匹配的数据,则展示为 null

自连接

站在不同角度,把一张表看成多张表

--查询出员工姓名,员工部门名称,员工领导姓名,员工领导部门名称
select e1.ename, d1.dname, e2.ename, d2.dname
from emp e1,emp e2, dept d1, dept d2
where e1.mgr= e2.empno
and e1.deptno=d1.deptno
and e2.deptno=d2.deptno;

Oracle 专用语法

左连接

select *
from emp e,dept d
where e.deptno=d.deptno(+);

右连接

select *
from emp e,dept d
where e.deptno(+)=d.deptno;

Tip

为了代码可重用,建议用通用语法

分页查询

rownum: 当我们做 select 操作的时候,每查询出一行记录,就会在该行上加上一个行号,行号从 1 开始,依次递增,不能跳着走。

排序操作 (order by) 会影响 rownum 的顺序

select rownum, e.* from emp e order by e.sal desc;

如果涉及到排序,还要使用 rownum 的话,我们可以再次嵌套查询。

r1 是顺序,r2 的顺序被打乱

select rownum r1, t.* from(
select rownum r2, e.* from emp e order by e.sal desc) t;

每页五条记录,查询第二页 (分页查询时,条件不能写 rownum 大于一个正数)

select * from (
    select rownum rn,e.* from (
        select * from emp order by sal desc
    ) е where rownum <= 10 --offset=pageSize*pageNum
) where rn > 5 --pageSize*(pageNum-1)

分页模版

pageSize=5, offset=pageSize*pageNum