表的查询
1、简单查询
1)、打开显示操作的时间开关
SQL>set timing on;
SQL>select * from emp;
SQL>select ename from emp;
注意:对于大数据表格,尽量不要用select * ,而需要指明需要查找的字段名字。 举例,伪造大量数据:
SQL>insert into users values(‘a001’,’hahhahahah’,’123456678899’);
SQL>insert into users (userid,username,userpss) select * from users;
SQL>insert into users (userid,username,userpss) select * from users;
2)、select distinct deptno,job from emp; 取消重复行
3)、算术表达式
SQL>select sal*13 “年工资” from emp;
注意:如果表达式中有一个字段为null,则整个表达式的值为null;处理方法如下:
SQL>select sal*13+nvl(comm,0)*13 “年工资” from emp; —–>使用nvl函数来判断 null
4)、where子句
SQL>select ename,hiredate from emp where hiredate >’1-1月-1982’;—>注意:日期格 式
多个条件用and隔开
5)like子句
%:表示任意0到多个字符
_:表示任意单个字符
6)in子句,比用or查询速度快
SQL>select * from emp where empno in(123,456,222);
7)逻辑操作符
SQL>select * from emp where (sal>500 or job=’MANAGER’) and name like ‘J%’;
8)order by 子句(默认从低到高),降序desc
例:按照部门号升序而雇员的工资降序排列
SQL>select * from emp order by deptno asc , sal desc;
2、复杂查询
1)查询工资最高的员工名字和工资:
SQL>select ename,sal from emp where sal=(select max(sal) from emp);
2)group by 和having子句
例:显示每个部门的平均工资和最高工资
SQL>select avg(sal),max(sal),deptno from emp group by deptno;
例:显示每个部门的每种岗位的平均工资和最低工资
SQL>select avg(sal),max(sal),deptno,job from emp group by deptno,job;
例:显示平均工资低于2000的部门号和它的平均工资
SQL>select avg(sal),max(sal),deptno from emp group by deptno having avg(sal)>2000;
3)总结:
a.分组函数只能出现在选择列表、having、order by子句中;
b.如果在select语句中同时包含有group by,having,order by,那么他们的执行顺 序是group by,having,order by;
c.在选择列中有列、表达式和分组函数,那么这些列和表达式必须有一个出现在
group by子句中,否则就会出错。
3、多表查询
1)显示雇员名,雇员工资及所在部门的名字
SQL>select a1.ename,a1.sal,a2.deptno from emp a1,dept a2 where a1.deptno=a2.deptno;
注意:如果不加条件就是笛卡尔积,为避免出现,则规律是多表查询的条件个数
至少不能少于表的个数-1。
2)显示部门号为10的部门名、员工名和工资
SQL>select a1.dname,a2.ename,a2.sal from dept a1,emp a2 where a1.deptno =a2.deptno and a1.deptno=10;
3)显示各个员工的姓名,工资,及其工资的级别
SQL>select a1.ename,a1.sal,a2.grade from emp a1,salgrade a2 where a1.sal between
a2.losal and a2.hisal;
4)显示雇员名,雇员工资及所在部门的名字,并按部门排序
SQL>select a1.ename,a2.dname,a1.sal from emp a1,dept a2 where a1.deptno=a2.deptno order by a1.deptno;
5)自连接:指在同一张表的连接查询。
例:显示雇员FORD的上级:
SQL>select worker.ename,boss.ename from emp worker,emp boss where worker.mgr=boss.empno and worker.ename=’FORD’;
4、子查询:指嵌入在其它sql语句中的select语句,也叫嵌套查询。
1)单行子查询,指只返回一行数据的子查询语句
例:如何显示与SMITH同一部门的所有员工:
a.查询出smith的部门号:select deptno from emp where ename = ‘SMITH’;
b.显示:select * from emp where deptno=(select deptno from emp where ename = ‘SMITH’);
2)多行子查询
例:如何查询和部门10的工作相同的雇员的名字、岗位、工资、部门号:
a.查询出部门10的所有岗位:select distinct job from emp where deptno=10;
b.显示:select * from emp where job in (select distinct job from emp where deptno=10);
3)多行子查询使用all操作符
例:如何显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号:
select ename,sal,deptno from emp where sal >all(select sal from emp where deptno=30);
select ename,sal,deptno from emp where sal >(select max(sal) from emp where deptno=30); —–>效率比上句高,Oracle是从右往左扫描的。
4)多行子查询使用any操作符
例:显示工资比部门30的任意一个员工的工资高的员工的姓名、工资和部门号
select ename,sal,deptno from emp where sal>any(select sal from emp where deptno=30);
5)多列子查询
例:查询与smith的部门和岗位完全相同的所有雇员:
a.查询smith的部门号,岗位:select deptno,job from emp where ename=’SMITH’;
b.显示:select * from emp where (deptno,job)=( select deptno,job from emp where
ename=’SMITH’);
例:显示高于自己部门平均工资的员工的信息:
a.查询出各个部门的平均工资和部门号:select deptno,avg(sal) mysal from emp group by deptno;
b.把上面的查询看做是一张子表:select a2.ename,a2.sal,a2.deptno,a1.mysal from
emp a2,( select deptno,avg(sal) mysal from emp group by deptno) a1 where a2.deptno=a1.deptno and a2.sal>a1.mysal;
6)总结:当在from子句中使用子查询时,该子查询会被作为一个视图来对待,
因此叫做内嵌视图,当在from子句中使用子查询时,必须给予查询指定别名,而 且此处不能加as。
7)使用子查询插入数据
当使用values子句时,一次只能插入一行数据,当使用子查询插入数据时,一条
insert语句可以插入大量的数据。当处理行迁移或者装载外部表的数据到数据库时, 可以使用子查询来插入数据。
SQL>create table kkk(myId number(4),myname varchar2(50),myDept number(5));
SQL>insert into kkk(myid,myname,mydept) select empno,ename,deptno from emp where deptno =10;
8)使用子查询更新数据
例:希望员工scott的岗位、工资、补助与smith员工一样
SQL>update emp set (job,sal,comm)=(select job,sal,comm from emp where ename=’SMITH’) where ename=’SCOTT’;
5、分页查询
1)oracle分页一共有三种方式
a).rownum分页,效率中等
SQL>select * from emp;
SQL>select a1.,rownum rn from (select from emp) a1 where rownum<=10 —–>此
处条件只能用rownum,且rownum只能使用一次;
SQL>select * from (select a1.,rownum rn from (select from emp) a1 where
rownum<=10) where rn>4;
注意:不管是指定查询列还是排序,只需修改最里层的子查询,比如:
SQL> select * from (select a1.*,rownum rn from (select ename,sal from emp) a1
where rownum<=10) where rn>4;
SQL> select * from (select a1.*,rownum rn from (select ename,sal from emp order by
sal) a1 where rownum<=10) where rn>4;
b).rowid分页,效率最好
SQL> select rowid rid,sal from emp order by sal desc—–>获取数据物理地址
SQL> select rownum rn,rid from (select rowid rid,sal from emp order by sal desc)
where rownum<8—–>取得最大页数
SQL> select rid from (select rownum rn,rid from (select rowid rid,sal from emp order
by sal desc) where rownum<8) where rn >5 —–>取得最小页数
SQL>select * from emp where rowid in (select rid from (select rownum rn,rid from
(select rowid rid,sal from emp order by sal desc) where rownum<8) where
rn >5) order by sal desc; —–>因为取得的页数都是物理地址,再根据物理 地址,查询出具体数据。
c).row_number()分页,效率最差
SQL>select * from (select t.*,row_number() over(order by cid desc) rk from t_xiaoxi t) where rk<10000 and rk>9980
6、用查询结果创建新表,可以创建一个测试表,进行测试
SQL>create table mytable (id,name,sal,job,deptno) as select
empno,enmae,sal,job,deptno from emp;
7、合并查询,合并多个select的查询结果。了解部分。
1)union,取得并集
SQL>select ename,sal,job from emp where sal>2500 union select ename,sal,job from
emp where job=’MANAGER’;
2)union all,不会去掉重复行
3)intersect,取交集
4)minus,取差集
注意:效率比and、or等语法快。