复习一下SQL

我们是JAVA开发,不是DBA,所以没有必要在数据库管理上下很大功夫,下再多的功夫也比不过专业的管理人员做得好,术业有专攻,不要期望一个人把所有的事情都干了。


SQL 结构化查询语言


关系型数据库 oracle mysql sqlserver db2


sql分类:
1.查询语句 
2.DML(Data Manipulation Language) 数据操作语言(insert,update,delete) 语句
3.DDL(Data Definition Lanaguage) 数据定义语言(create,alter,drop)语句
4.事务控制语句(Transaction Control) commit,rollback等语句




 emp表,dept表,salgrade表,bonus表-->空表
--查询所有的表
select * from tabs;
--describe bonus;  desc tableName;查看表结构。


oracle常用数据类型
varchar2(n) 变长字符串,存储空间等于实际空间的数据大小,最大为4K
char(n) 定长字符串
Long 变长字符串 最大字节数达到2GB
number(p,s)有效位数或者小数


--检索单个列
select ename from emp;
--检索多个列
select ename,eno from emp;
--检索所有列
select * from emp;
--别名
select ename "工作" ,sal from emp;
--双引号一般用来起别名 ,'单引号表示字符串的引用
--查询每个人的年薪
select ename,sal*12 from emp;
--获取系统时间
select sysdate from emp;
--空表 测验
select 2*3 from dual;
--计算每个人的全年收入包括月薪和年终奖
select ename,sal*12+nvl(comm,0) from emp;
--nvl函数,如果这个字段为空的话,就把值设置成0
--字符串拼接;比如每个人的薪水:格式为smith-sal-123
select ename ||'-'||sal||'-'||comm from emp;
--两个单引号表示转义''






===========================================================================
排序检索出的数据,按照sql规范,如果不显式制定数据排序,则认为数据排序是无意义的。
--order by  column  默认为升序 asc(ascend),降序为desc(descend);
===========================================================================
where 过滤
=,<>,!=,<,>,<=,>=, between..and.., is null, is not null
--部门编号是10的部门员工
select * from emp where deptno='10'
select * from emp where ename='KING';
select * from emp where ename>'CBA';
select * from emp where sal between 800 and 1500;
select * from emp where sal >=800 and sal<=1500;
select ename,hiredate,comm from emp where comm is not null;


--where子句的组合应用 and  or
select * from emp where (deptno=30 or deptno=10) and sal>2000;
-- sql里面优先处理and


*********************************************************
sql优化问题:
AND:把检索结果较少的条件放到前面 

select 10000行 as 'A' and  10行 as 'B';
select 10行 as 'B' and 10000行 as 'A' ---->>正确的
or-相反
********************************************************
in 操作符
select * from emp where deptno on in (10,20,30); 
-- in 操作符一般比or操作符执行更快
***********************************************************
like操作符 %表示任意字符出现任意次数  _表示出现一次
select * from emp where ename like '%A%';
select * from emp where ename like 'A%';
技巧和注意事项:
1.不能过度使用通配符,如果其他操作符能达到目的,就不要使用通配符
2.确实需要使用通配符的时候,除非绝对必要,否则不能把通配符用到搜索的最开始处,因为这样搜索起来是最慢的。

***************************************************************
Oracle10g新特性:正则表达式的使用
select * from emp where regexp_like(ename,'[SM].');
***************************************************************
创建计算字段  比如说拼接,使用别名,执行算术计算等
 
处理null的字段 nvl(null,0);
文本处理函数 Lower(),upper(),substr(),length(),trim(),ltrim(),rtrim();
to_date(),to_number();


select ename,lower(ename) from emp;
--给函数的计算字段起一个别名
select ename,lower(ename) "dddd" from emp;


select ename,substr(ename,1,3) from emp;
--从二开始到结束
select ename,sbsstr(ename,2) from emp;


时间处理函数
to_char(),sysdate(oracle)


select to_date('2004-09-19','yyyy-mm-dd') from dual;
数值处理函数
round() 四舍五入
abs() 取绝对值
floor();下取整(19.9-->19)
cell();上取整(19.9-->20)
avg(),
max(),
min(),
count()
**********************************************************
组函数,统计函数 avg(),max(),min(),sum(),count(*)
select avg(sal) from emp;
--null值不计入
select avg(comm) from emp;
--null值计入的话则
select avg(nvl(comm,0) ) from emp;
select count(distinct sal) from emp;


**********************************************************

数据分组

什么是组 ,值相同则为一组,比如deptno=10  可以将此作为一组

分组允许把数据分为多个逻辑组,然后以逻辑组为单位进行数据汇总
创建分组(Group By 子句必须出现在where子句之后,order by 子句之前)
除 组函数计算语句外,select 语句中的每个列都必须在group by字句中给出.

上面的语句将会报错,这是因为如果按照deptno进行分组的话,每组会有一个薪水最大值,但是每个组里面有多个名字,不能够产生唯一的ename,这就出现了不匹配。
按照deptno分组,计算每个部门中的员工的最高薪水是多少?
select max(sal),deptno from emp group by deptno;--分组查出来的都是对应的唯一值,这里deptno分组后对应的sal不是唯一的,所以这里不能用sal,可以用统计函数找到唯一值。




where 是以行为单位过滤  group by 是以组来过滤,值相同即为一组。

select ename,avg(sal),deptno from emp group by deptno;//报
组里面有平均薪水,但是没有固定的名字


组函数嵌套最多两层
求平均薪水最高的部门
select max(avg(sal)) from emp group by deptno;


分组的过滤
where 过滤行 having过滤分组 having支持所有where操作符
select avg(sal),deptno from emp group by deptno having avg(sal)>2000;
where 在数据分组前进行过滤,having在数据分组后进行过滤,这是一个重要的区别,where排除的行不包括在
分组中,这可能会改变计算值,从而影响having子句中觊觎这些值过滤掉的分组
**********************************************************************************
分组和排序
一般使用group by 子句时,应该也给出order by 子句,这是保证数据正确排序的唯一方法。
select avg(sal),deptno from emp group by deptno having avg(sal)>2000 order by deptno;
select 子句的排列顺序:
select  from   where group by having order by
执行顺序:
1.先执行where子句进行行级过滤
2.将where子句过滤后的结果,进行分组
3.将分好组的数据进行组级别的过滤
4.最后将最终数据进行排序

******************************************************************************************

子查询
嵌套在其他查询中的查询 即查询套查询
子查询是由内而外执行
子查询时 注意格式,不然阅读起来比较困难
返回一个字段多行记录时,用in
select empno,ename from emp where empno in (select distinct mgr from emp);
返回一个值时,可以用=,<,>等
有哪些人的薪水是在整个雇员的评价薪水之上的:
select ename,empno,sal,sal+nvl(comm,0) from emp where sal+nvl(comm,0)>select avg(sal+nvl(comm,0)) from emp);
From子句中写子查询
返回多字段的记录时,使用
比如求每个部门的薪水等级
可以这样考虑,
首先将每个部门的平均薪水求出来,然后把结果当成一张表,再用这张表和salgrade做连接,以此求得薪水等级
select * from
salgrade s,(select deptno,avg(sal) avg_sal from emp group by deptno)t
where t.avg_sal between s.local and s.hisal;
求平均薪水最高的部门的部门编号
select deptno from emp group by deptno  having avg(sal)=(select max(avg(sal) from emp group by deptno));
求比普通员工的最高薪水还要高的经理人的名称
******************************************
oracle和mysql的分页技术
Oracle的rownum是一个伪列,从1开始以此递增,但是rownum只能使用<,<=,不能使用>,>=
select rownum,ename from emp where rownum<=5;

而且当rownum和order by一起使用的时候,会首先筛选出符合rownum条件的记录,然后再进行排序,这会给我们的
查询带来难度。如 我们要求查询出薪水最高的5个人的时候,
select ename,sal from emp where rownum<=5 order by sal desc;
但是因为这个where语句首先过滤掉了其他行,所以出来的结果并不是薪水最高的前五个人。
要用子查询
select r,ename,sal from (select rownum r,ename,sal from (select * from emp order by sal desc)) where r<9 and r>5;---->这是oracel最有效率的分页查询
mysql里面做分页很简单, select * from emp where sal>1000 limit 5,10
*************************************************************
表连接

SQL最强大的功能之一就是能在数据查询的执行中联结表
笛卡尔积  检索出的行的数目将是第一个表中的行数乘以第二个表中的行数
应该保证所有联结都有where子句 不然数据库返回比想象的数据多得多的数据
完全限定列名:
在引用的列出现二义性时,必须使用完全限定列名(用一个句点分隔的表名和列名)
select ename,emp.deptno,dname from emp ,dept where emp.deptno=dept.deptno;

自联结
自连接通常都作为外部语句用来替代从相同表中检索数据的使用子查询语句,虽然最终的结果相同,但是一般情况
很多软件的自连接的处理速度比处理子查询速度快得多
--检索出雇员姓名和该雇员的经理的姓名
自连接用法:
select e1.ename "employee", e2.ename "manager" from emp e1,emp e2 where e1.mgr=e2.empno;
子查询用法:
select e1.ename,e2.ename from emp e1,(select ename,mgr from emp ) e2 where e1.mgr=e2.empno;

在where子句中进行多表连接
select ename,dname from emp join dept on emp.deptno=dept.deptno where emp.deptno=30;
内连接(一般用它,只显示符合条件的行)
select dname,ename from emp  join dept on emp.deptno=dept.deptno;
左外连接

*************************************************************
视图是虚拟的表,或者说就是一个子查询,只不过这个子查询有自己的名字,我们可以直接
访问子查询的结果,适当的利用视图,可以使我们的查询变得简单
************************************************************

你可能感兴趣的:(日常)