1 函数
函数
函数一般是数据库上执行的,用于对数据的转换和处理,不改变数据库中的值。
函数分为单行函数和聚合函数。
聚合函数又称组函数,用于对多行数据进行操作,返回的结果单一,组函数仅可用于选择列表或查询的having子句。
单函数对于单个数值进行操作,并返回一个值。
字符型函数
select *from dual;
数值型函数
例如:求余数
select mod(9,2) from dual;
日期函数
select sysdate from dual;
例如:查询工作年限在30年以上的
select e.ename, e.hiredate
from emp e
where months_between(sysdate,e.hiredate)/12>30;
查询会话的环境参数
select * from nls_session_parameters;
next_day(date1,week) 返回date1下周星期几的日期
select sysdate "当时日期",next_day(sysdate,'Monday') "下周星期一" from dual;
日期计算函数
注意:两个日期间进行的四则运算单位是天。
select sysdate+2 from dual;
转换函数
转换函数就是把字符、日期、数值型数据进行相互转换,
转换类型:隐式转换和显式转换
隐式转换
select '100' - 10 from dual;
显式转换
to_char
把日期转换成字符
把数值转换成字符串
to_char
-- 【1】把日期转化成字符
-- 按照默认格式DD-MON-RR
select to_char(sysdate) from dual;
-- 按指定格式
select to_char(sysdate,'YYYY"年"MM"月"DD"日" HH24:MI:SS') as t from dual;
-- 【2】把数值格式化成字符串
select to_char(12345,'99999.99') from dual;
select to_char(12345,'99,999.99') from dual;
select to_char(12345,'999,999.99') from dual;
-- 不够位置0
select to_char(12345,'000,000.00') from dual;
-- 格式化成美元显示
select to_char(12345,'$000,000.00') from dual;
to_number、to_date
select to_number('$12,345','$99,999') from dual;
select to_number('$12,345.12','$99,999.99') from dual;
-- to_date
select to_date('14-May-19','DD-MON-RR') from dual;
select to_date('2004-09-19','YYYY-MM-DD') from dual;
函数可以嵌套
查询雇用期满6个月的下一个周一的日期。
select e.ename,e.hiredate,next_day(add_months(e.hiredate,6),'Monday')
from emp e
where months_between(sysdate,e.hiredate) > 6
-- 查询公司boss
select e.ename || nvl(to_char (e.mgr), 'is boss')
from emp e
where e.mgr is null;
decode/case when
decode (条件,值1.。。。。)
select e.ename, e.deptno
decode(
e.deptno,10,('部门1',20,'部门2',30,'部门3','未知')
from emp e;
组函数
组函数把多行数据经过运算后返回单个值。也称聚合函数。
求公司雇员的数量
select count(*)
from emp e;
select count(e.empno)
from emp e;
select count(1)
from emp e;
-- avg:对多个记录的某个字段求平均值
-- 需求:求底薪的平均值
select avg(e.sal)
from emp e;
-- 需求:求雇员的最高薪资/最低薪资
select max(e.sal),min(e.sal),avg(e.sal)
from emp e;
组函数或聚合函数是对一个数据集(表数据、查询出来的表、分组的表)进行聚合。
聚合函数对字段是null的值进行忽略。count(*)
max/min 适合任意数据类型,sum/avg 只适用于数值类型。
聚合函数的结果可以作为其他查询条件。
分组(group by)
在处理统计或聚合数据时,很多时候需要对数据进行分组,语法为
select field1,。。。
from tableName
group by field1[,field2,…]
group by的工作原理
对数据进行分组后,select语句的字段值只能是分组字段或者聚合函数。
分组和聚合函数
select e.deptno
from emp e
group by e.deptno;
null值归为一组
select e.comm,count(1)
from emp e
group by e.comm
having
如果需要对分组的数据进行条件过滤,必须使用having!!!
查询部门平均薪资大于3000的部门
select e.deptno
from emp e
group by e.daptno
having avg(e.sal)>3000
查询部门薪资大于3000的雇员按部门分组的平均薪资
select e.deptno,avg(e.sal)
from emp e
where e.sal > 3000
group by e.deptno;
注意: WHERE只对行过滤,而having 过滤分组。
Having 支持所有where操作符。
排序 (order by)
asc 升序 默认
desc 降序
order by
-- 需求:按雇员薪资排序
select e.ename,e.sal
from emp e
order by e.sal desc
-- 按薪资升序,名称降序
select e.ename,e.sal
from emp e
order by e.sal,e.ename desc;
需求: 查询 薪资大于1200的 雇员在部门中平均薪资大于1500的部门,按照平均薪资升序排序。
select e.deptno,avg(e.sal)
from emp e
where e.sal > 1200
group by e.deptno
having avg(e.sal) > 1500
order by avg(e.sal) asc
order by 既可以用于数据行(记录)排序。
也可以对分组的结果进行排序,此时需要聚合函数配合。
Select 语言的执行顺序
- 读取from子句中的基本表、视图的数据,[执行笛卡尔积操作]。
- 选取满足where子句中给出的条件表达式的元组
- 按group子句中指定列的值分组,同时提取满足Having子句中组条件表达式的那些组
- 按select子句中给出的列名或列表达式求值输出
- Order by子句对输出的目标表进行排序。
from > where > group by > having > select > order by
多表关联
笛卡尔积(C)
笛卡尔积
select *
from emp,dept
等值连接
-- 需求:查询雇员的部门名称
select e.ename,e.deptno,d.dname
from emp e,dept d
where e.deptno = d.deptno
不等值连接
- 查询每个雇员的薪资等级
select e.ename,e.sal,sg.grade
from emp e,salgrade sg
where e.sal >= sg.losal and e.sal <= sg.hisal
外连接(B)
左外连接:左边的表作为主表,右边表作为从表,主表数据都显示,从表数据没有,用null填充,用+号表示。
select *
from dept d,emp e
where d.deptno = e.deptno(+)
右外连接: 右边的表作为主表,左边表作为从表,主表数据都显示,从表数据没有,用null填充,用+号表示。
select *
from emp e,dept d
where e.deptno(+) = d.deptno;
自连接
一个表自身连接自身时,称为自连接。自连接以不同的视角看待同一张表。
查询每个雇员的上级领导
select e.ename "雇员",m.ename "领导"
from emp e,emp m
where e.mgr = m.empno
-- 优化king
select e.ename "雇员",nvl(m.ename,'boss') "领导"
from emp e,emp m
where e.mgr = m.empno(+)
多于两张表的查询
如果有多个表参与查询,先把t1xt2笛卡尔积得到一个大表T1,再把T1xt3笛卡尔积得到一个另外的大表T2,依次类推。
所有的多表查询最终都是两种表的查询。