oracle学习分组查询子查询

时间:2023-02-23 15:15:27
oracle学习总结
group by 与order by运用
having运用与where区别
-------------------------------------------------------------------------
group by 和 having子句 
group by用于对查询的结果分组统计, 
having子句用于限制分组显示结果。 
问题:如何显示每个部门的平均工资和最高工资? 
SELECT AVG(sal), MAX(sal), deptno FROM emp GROUP by deptno; -----先分组,再聚合。
(注意:这里暗藏了一点,如果你要分组查询的话,分组的字段deptno一定要出现在查询的列表里面,否则会报错。因为分组的字段都不出现的话,就没办法分组了) 

问题:显示每个部门的每种岗位的平均工资和最低工资? 
SELECT min(sal), AVG(sal), deptno, job FROM emp GROUP by deptno, job; 
问题:显示平均工资低于2000的部门号和它的平均工资? 
SELECT AVG(sal), MAX(sal), deptno FROM emp GROUP by deptno having AVG(sal) < 2000; --很容易错

对数据分组的总结 
1 分组函数只能出现在选择列表、having、order by子句中(不能出现在where中) 
2 如果在select语句中同时包含有group by, having, order by 那么它们的顺序是group by, having, order by 
3 在选择列中如果有列、表达式和分组函数,那么这些列和表达式必须有一个出现在group by 子句中,否则就会出错。 

SELECT deptno, AVG(sal), MAX(sal) FROM emp GROUP by deptno HAVING AVG(sal) < 2000; 
这里deptno就一定要出现在group by 中 
多表查询 
说明
多表查询是指基于两个和两个以上的表或是视图的查询。在实际应用中,查询单个表可能不能满足你的需求,(如显示sales部门位置和其员工的姓名),这种情况下需要使用到(dept表和emp表) 
问题:显示部门号为10的部门名、员工名和工资? 
SELECT d.dname, e.ename, e.sal FROM emp e, dept d WHERE e.deptno = d.deptno and e.deptno = 10; 
问题:显示各个员工的姓名,工资及工资的级别? 
先看salgrade的表结构和记录 
SQL>select * from salgrade; 
 GRADE              LOSAL             HISAL 
-------------  -------------     ------------ 
    1                      700                1200 
    2                      1201              1400 
    3                      1401              2000 
    4                      2001              3000 
    5                      3001              9999 
SELECT e.ename, e.sal, s.grade FROM emp e, salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal; 

扩展要求: 
问题:显示雇员名,雇员工资及所在部门的名字,并按部门排序? 
SELECT e.ename, e.sal, d.dname FROM emp e, dept d WHERE e.deptno = d.deptno ORDER by e.deptno; 
(注意:如果用group by,一定要把e.deptno放到查询列里面) 
自连接
自连接是指在同一张表的连接查询 
问题:显示某个员工的上级领导的姓名? 
比如显示员工‘FORD’的上级 
SELECT worker.ename, boss.ename FROM emp worker,emp boss WHERE worker.mgr = boss.empno AND worker.ename = 'FORD';      
子查询 
--------------------------------------------------------------------------------------------
什么是子查询
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。 
单行子查询 
单行子查询是指只返回一行数据的子查询语句 
请思考:显示与SMITH同部门的所有员工? 
思路:
1 查询出SMITH的部门号 
select deptno from emp WHERE ename = 'SMITH'; 
2 显示 
SELECT * FROM emp WHERE deptno = (select deptno from emp WHERE ename = 'SMITH'); 
数据库在执行sql 是从左到右扫描的, 如果有括号的话,括号里面的先被优先执行。 

多行子查询
多行子查询指返回多行数据的子查询 

请思考:如何查询部门编号为10的工作相同的雇员的名字、岗位、工资、部门号 
SELECT DISTINCT job FROM emp WHERE deptno = 10; 
SELECT * FROM emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno = 10); 
(注意:不能用job=..,因为等号=是一对一的) 
 在多行子查询中使用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); 
执行效率上, 函数高得多 

在多行子查询中使用any操作符
问题:如何显示工资比部门30的任意一个员工的工资高的员工姓名、工资和部门号? 
SELECT ename, sal, deptno FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE deptno = 30); 
扩展要求: 
大家想想还有没有别的查询方法。 
SELECT ename, sal, deptno FROM emp WHERE sal > (SELECT min(sal) FROM emp WHERE deptno = 30);

多列子查询
单行子查询是指子查询只返回单列、单行数据,多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询是指查询返回多个列数据的子查询语句。 
请思考如何查询与SMITH的部门和岗位完全相同的所有雇员。 
SELECT deptno, job FROM emp WHERE ename = 'SMITH'; 
SELECT * FROM emp WHERE (deptno, job) = (SELECT deptno, job FROM emp WHERE ename = 'SMITH'); 
在from子句中使用子查询
请思考:如何显示高于自己部门平均工资的员工的信息 
思路: 
1. 查出各个部门的平均工资和部门号 
SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno; 
2. 把上面的查询结果看做是一张子表 
SELECT e.ename, e.deptno, e.sal, ds.mysal FROM emp e, (SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno) ds WHERE e.deptno = ds.deptno AND e.sal > ds.mysal; 
如何衡量一个程序员的水平? 
网络处理能力, 数据库, 程序代码的优化程序的效率要很高 
小总结: 
在这里需要说明的当在from子句中使用子查询时,该子查询会被作为一个视图来对待,因此叫做内嵌视图,当在from子句中使用子查询时,必须给子查询指定别名。 
注意:别名不能用as,如:SELECT e.ename, e.deptno, e.sal, ds.mysal FROM emp e, (SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno) as ds WHERE e.deptno = ds.deptno AND e.sal > ds.mysal; 
在ds前不能加as,否则会报错? (给表取别名的时候,不能加as;但是给列取别名,是可以加as的) 
2.外键
插入表的时候,如果插入的是外键,那么这个外键必须先定义(也就是先插入外键所在表的主键值),否则报什么父对象异常;
删除的时候相反,如果要删除一个表的主键,然后才可以删除该主键对应的外键。
create table t_test1(id number primary key,subID number);
create table t_test2(id number primary key);
alter table t_test1
  add constraint FK_test1_subID foreign key (subID)
  references T_test2 (id);

7.数据库,表的导出(plsql developer)
ok

10.rownum 
要使用必须用排序的子查询,而且必须使用rownum<n才行,如果使用rownum>n查出是无序的
   (n,m)
select   t2.*  from(t1.* ,rownum rn from (

) t1 where rownum<m) t2 ) where rn >n;

11.序列的运用(深入讲下序列运用)
insert into t_car(carno,carType,DISPLACEMENT,PRICE,PRODUCTDATE) values(seq_student.nextval,'mini',1.2,100000,sysdate);
select seq_student.currval from dual; --当启动系统时候只有运行一下next才可以调用

解锁scott用户,必须system用户
alter user scott account unlock;
设置密码
password scott/XXXX;