• 逆袭之旅DAY14.东软实训.Oracle.多表连接、分组函数、子查询


    2018-07-10 08:29:55

     

     

    思考应用场景

    异常数据的测试

    
    

    6.显示能挣得奖金的雇员的姓名、工资、奖金,并以工资和奖金降序排列。
    select ename,sal,comm
    from emp
    WHERE comm>0
    --两列都要desc
    order by sal desc,comm desc;

    
    

    8. 显示姓名中两次出现字母L并且在30部门工作,或者其管理员编号是7782的雇员的姓名。
    SELECT ename
    FROM emp
    --模糊查询
    WHERE ename LIKE '%L%L%'
    AND deptno=30 OR mgr=7782;

    
    

    7. 显示雇员的姓名、受雇日期及受雇当天是星期几(列标题为DAY),并以DAY升序排列

    
    

    SELECT ename,hiredate,TO_CHAR(hiredate,'DAY') "DAY"
    FROM EMP
    --ORDER BY TO_CHAR(hiredate,'DAY'); 'DAY'是乱序
    ---'D'按 日,一,二,...六 排序
    ORDER BY TO_CHAR(hiredate,'D');

    
    

    5.查询员工的姓名及其经理编号,要求对于没有经理的显示“No Manager”字符串。
    SELECT * FROM emp;
    SELECT ename,nvl(to_char(mgr),'No Manager')
    FROM emp

    
    

    4. 编写一个以下面的形式输出的查询:
    <employee name> earns <salary> monthly but wants <3 times salary>.
    列标题为Dream Salaries。
    ---列起别名 中间有空格 "Dream Salaries"
    SELECT 'employee'||ename || ' earns ' || sal || ' monthly but wants ' || sal * 3 "Dream Salaries"
    FROM emp;

    
    

    --7.显示姓名中第三个字母为A的雇员的姓名。
    select ename
    FROM emp
    where instr(substr(ename,3,1),'A')>0;

    
    

    (3)显示雇员姓名并以*为指示符代表工资数额(列标题为EMPLOYEE_AND_THEIR_SALARIES),一个指示符代表一百美元,并以工资数额降序排列。
    --rpad('原字符',num,'填充的符号') (原字符+填充的符号)=num
    SELECT ename || rpad('*',trunc(sal/100),'*') EMPLOYEE_AND_THEIR_SALARIES
    FROM emp
    ORDER BY sal desc;

    一、多表查询
    SELECT 列名,列名...
    FROM 表名 表的别名,表名 表的别名....
    WHERE 条件
    ORDER BY 排序字段。。。

    1、笛卡尔积:是多张表记录的乘积。
    SELECT *
    FROM emp,dept
    WHERE ename='SMITH';

    SELECT * FROM emp;
    SELECT * FROM dept;

    SELECT ename,emp.deptno,dname
    FROM emp,dept;

    ---*****
    2、等值连接,两张表中存在含义相同,值相等的列的
    SELECT *
    FROM emp,dept
    WHERE emp.deptno=dept.deptno;

    SELECT a.deptno,ename,dname
    FROM emp a,dept b
    WHERE A.deptno=b.deptno
    ORDER BY A.deptno;

    ---工资等级
    3、不等值连接
    SELECT * FROM salgrade;

    SELECT *
    FROM emp A,salgrade b
    --WHERE a.sal >=b.losal and a.sal<=b.hisal;
    WHERE sal between losal and hisal;

    ---查询员工的姓名,员工的部门名称,员工的工资等级
    SELECT ename,dname,grade
    FROM emp,dept,salgrade
    WHERE emp.deptno=dept.deptno AND sal BETWEEN losal AND hisal;

    ---员工 经理
    4、自身连接:
    SELECT * FROM emp;

    SELECT *
    FROM emp A,emp b
    ---员工的经理编号=经理的员工编号
    WHERE a.ename='SMITH' and a.mgr = b.empno;

    SELECT *
    FROM emp A,emp b
    WHERE A.mgr = b.empno;

    ---查询员工的姓名,员工的部门名称,员工的工资等级,员工对应的领导姓名,领导的部门名称,领导的工资等级
    SELECT e.ename 员工姓名,d.dname 员工的部门名称,s.grade 员工的工资等级,m.ename 领导的姓名,md.dname 领导的部门名称,ms.grade 领导的工资等级
    FROM emp e,dept d,salgrade s,emp m,dept md,salgrade ms
    WHERE e.deptno=d.deptno AND e.sal BETWEEN s.losal AND s.hisal AND e.mgr=m.empno AND m.deptno=md.deptno
    and m.sal between ms.losal and ms.hisal;

    
    

    5、外连接:
    SELECT *
    FROM emp,dept
    ---右边的全显示,左边没有的话,用null值填充
    WHERE emp.deptno(+)=dept.deptno;

    
    

    SELECT *
    FROM emp,dept
    ---左边的全显示,左边没有的话,用null值填充
    WHERE dept.deptno=emp.deptno(+);

    
    

    6、SQL1999:
    (01)CROSS JOIN:交叉连接,笛卡尔积
    语法:table1 CROSS JOIN table2

    
    

    SELECT *
    FROM emp CROSS JOIN dept;
    =
    SELECT *
    FROM emp,dept;

    
    

    ---*****
    (02)NATURAL JOIN:自然连接
    语法:table1 NATURAL JOIN table2

    
    

    SELECT *
    FROM emp NATURAL JOIN dept;

    
    

    (03)JOIN...USING(公共列名)
    语法:table1 JOIN table2 USING(公共列)

    
    

    SELECT *
    FROM emp JOIN dept USING(deptno);

    
    

    (4)JOIN...ON 连接条件
    语法:table1 join table2 on 连接条件;

    
    

    SELECT *
    FROM emp JOIN dept ON emp.deptno=dept.deptno;

    
    

    (05)LEFT JOIN...ON 连接条件
    语法:table1 LEFT JOIN table2 ON 连接条件

    
    

    SELECT *
    FROM dept left JOIN emp ON emp.deptno=dept.deptno;

    
    

    (06)RIGHT JOIN...ON 连接条件
    语法:table1 RIGHT JOIN table2 ON 连接条件

    
    

    SELECT *
    FROM emp RIGHT JOIN dept ON emp.deptno=dept.deptno;

    
    

    (07) FULL JOIN...ON 连接条件
    语法:table1 full JOIN table2 ON 连接条件

    
    

    SELECT *
    FROM emp e FULL JOIN emp m ON e.mgr = m.empno
    ORDER BY e.empno;

    
    

    二、分组查询
    1、分组函数:又称为统计函数,聚合函数
    sum():求和
    avg():求平均值
    MAX():求最大值
    MIN():求最小值
    count():求个数
    *:统计的表的记录数
    列名:统计该列不为null的个数

    注意:统计时,不对Null值进行处理

    
    

    SELECT sum(sal),avg(sal),MAX(sal),MIN(sal),count(empno)
    FROM emp;

    
    

    SELECT
    FROM
    WHERE
    GROUP BY 分组字段,分组字段。。。
    HAVING 组过滤条件
    ORDER BY

    
    


    ---按照职务不同来分组统计工资总和,人数
    SELECT job,sum(sal),count(empno)
    FROM emp
    GROUP BY job;

    
    

    ---查询emp表中不同的职务
    SELECT DISTINCT JOB
    FROM emp;

    
    

    SELECT JOB
    FROM emp
    GROUP BY JOB;

    
    

    ---查询不同的领导工号的个数
    SELECT count(distinct mgr)
    FROM emp;

    
    

    ---统计各个部门不同职务的员工薪水的总和,平均工资
    SELECT deptno,job,sum(sal),avg(sal)
    FROM emp
    GROUP BY deptno,JOB
    ORDER BY deptno;

    
    


    ---统计各个部门不同职务的员工薪水的总和,平均工资,部门名称,职务
    SELECT dname,JOB,sum(sal),avg(sal)
    FROM emp,dept
    WHERE emp.deptno=dept.deptno
    GROUP BY dname,JOB
    ORDER BY dname;

    
    

    ---统计各个部门不同职务的员工薪水的总和,平均工资,部门编号,部门名称,部门位置,职务
    SELECT dept.deptno,dname,loc,JOB,sum(sal),avg(sal)
    FROM emp,dept
    WHERE emp.deptno=dept.deptno
    GROUP BY dept.deptno,dname,loc,JOB
    ORDER BY dname;

    
    

    ---统计不同工资等级的员工人数,工资总和,工资平均值
    SELECT grade,sum(sal),round(avg(sal),2),count(empno)
    FROM emp,salgrade
    WHERE sal BETWEEN losal AND hisal
    GROUP BY grade;

    
    

    ---统计不同工资等级的员工人数,工资总和,工资平均值,要求员工的 人数要大于2
    SELECT grade,sum(sal),round(avg(sal),2),count(empno)
    FROM emp,salgrade
    WHERE sal BETWEEN losal AND hisal
    GROUP BY grade
    HAVING count(empno)>2;

    
    

    ---查询各个部门的平均工资大于2000的部门编号和平均工资
    SELECT deptno,avg(sal)
    FROM emp
    GROUP BY deptno
    HAVING avg(sal)>2000;

    
    

    where与having的区别:
    WHERE是在分组前进行过滤的,where的后面不能直接使用分组函数做比较
    HAVING是在分组后进行过滤的。

    
    

    3、分组函数的嵌套
    ---查询部门平均工资最高的平均工资
    SELECT MAX(avg(sal))
    FROM emp
    GROUP BY deptno;

    
    

    注意:当select后面的分组函数嵌套使用时,SELECT后面不能有任意列名,只能存在嵌套分组函数

    
    

    第六章课后作业:
    1.查询部门平均工资在2500元以上的部门名称及平均工资。
    SELECT dname,avg(sal)
    FROM emp,dept
    WHERE emp.deptno=dept.deptno
    GROUP BY dname
    HAVING avg(sal)>2500;
    2.查询员工岗位中不是以“SA”开头并且平均工资在2500元以上的岗位及平均工资,并按平均工资降序排序。
    SELECT JOB,avg(sal)
    FROM emp
    WHERE upper(JOB) NOT LIKE 'SA%'
    GROUP BY JOB
    HAVING avg(sal)>2500
    ORDER BY 2 desc;
    3.查询部门人数在2人以上的部门名称、最低工资、最高工资,并对求得的工资进行四舍五入到整数位。
    SELECT dname,round(MIN(sal)),round(MAX(sal))
    FROM emp,dept
    WHERE emp.deptno=dept.deptno
    GROUP BY dname
    HAVING count(empno)>2;
    4.查询岗位不为SALESMAN,工资和大于等于2500的岗位及每种岗位的工资和。
    SELECT JOB,sum(sal)
    FROM emp
    WHERE upper(JOB)!='SALESMAN'
    GROUP BY JOB
    HAVING sum(sal)>=2500;
    5.显示经理号码和经理姓名,这个经理所管理员工的最低工资,没有经理的KING也要显示,不包括最低工资小于3000的,按最低工资由高到低排序。
    SELECT m.empno,m.ename,min(e.sal)
    FROM emp e,emp m
    WHERE e.mgr=m.empno(+)
    GROUP BY m.empno,m.ename
    HAVING MIN(e.sal)>=3000
    ORDER BY min(e.sal) desc;
    6.写一个查询,显示每个部门最高工资和最低工资的差额
    SELECT deptno,MAX(sal)-MIN(sal)
    FROM emp
    GROUP BY deptno;

    
    

    4.使用ON子句,显示工作在CHICAGO的员工姓名,部门名称,工作地点,薪资等级
    select ename,dname,loc ,grade
    FROM emp JOIN dept ON emp.deptno =dept.deptno
    JOIN salgrade ON sal BETWEEN losal AND hisal
    WHERE dept.loc='CHICAGO';

    三、子查询
    子查询一般用()括起来
    子查询出现的位置:select,FROM,WHERE,HAVING
    嵌套子查询:一个查询语句中嵌套了另一个查询语句,子查询的语句可以直接运行

    
    

    单列子查询:子查询的返回结果是单行单列的,经常用在where,HAVING
    多行子查询:子查询的返回结果是单列多行的,经常用在where
    多列子查询:子查询的返回结果是多行多列的,经常用在from,where

    
    


    1、单列子查询
    ---查询与smith相同职务的其它员工信息
    SELECT JOB FROM emp WHERE lower(ename)='smith';

    
    

    SELECT *
    FROM emp
    WHERE job=(SELECT JOB FROM emp WHERE lower(ename)='smith') and lower(ename)!='smith';

    
    

    ------查询部门平均工资最高的平均工资和部门名称
    SELECT MAX(avg(sal))
    FROM emp
    GROUP BY deptno;

    
    

    SELECT dname,round(avg(sal),2)
    FROM emp JOIN dept ON emp.deptno=dept.deptno
    GROUP BY dname
    HAVING avg(sal)=(SELECT MAX(avg(sal))
    FROM emp
    GROUP BY deptno);

    2、多行子查询:
    集合运算:in
    ---查询与30部门职务相同的其它部门的员工信息
    SELECT distinct JOB FROM emp WHERE deptno=30;

    
    

    SELECT *
    FROM emp
    WHERE job in(SELECT distinct JOB FROM emp WHERE deptno=30) and deptno!=30;

    
    

    ANY:
    =ANY:相当于in
    SELECT *
    FROM emp
    WHERE job=any(SELECT distinct JOB FROM emp WHERE deptno=30) and deptno!=30;

    
    

    >ANY:比子查询返回结果的最小值要大
    ---查询比10部门的最低工资要高的其它部门员工信息
    SELECT *
    FROM emp
    WHERE sal>ANY(SELECT sal
    FROM emp
    WHERE deptno=10) and deptno!=10;

    
    

    <ANY:比子查询返回结果的最大值要小
    ---查询比20部门的最高工资要低的其它部门的员工信息
    SELECT *
    FROM emp
    WHERE sal<ANY(SELECT sal
    FROM emp
    WHERE deptno=20) and deptno!=20;

    ALL:
    =ALL:不存在现象
    >ALL:比子查询的返回结果的最大值要大
    ---查询比20部门所有人薪水都高的员工信息
    SELECT *
    FROM emp
    WHERE sal>all(SELECT sal FROM emp WHERE deptno=20);

    
    

    <ALL:比子查询的返回结果的最小值要小
    ---查询比10部门所有人薪水都低的员工信息
    SELECT *
    FROM emp
    WHERE sal<all(SELECT sal FROM emp WHERE deptno=10);

    
    

    3、多列子查询:
    ---查询与SCOTT用户工资和职务都匹配的其它员工的信息
    SELECT *
    FROM emp
    WHERE sal=(SELECT sal FROM emp WHERE upper(ename)='SCOTT')
    AND JOB=(SELECT JOB FROM emp WHERE upper(ename)='SCOTT')
    and upper(ename)!='SCOTT';

    SELECT *
    FROM emp
    WHERE (sal,job) in(SELECT sal,JOB FROM emp WHERE upper(ename)='SCOTT') and upper(ename)!='SCOTT';

    
    

    ---查询部门的名称,部门人数,部门最高工资,部门的最低工资,部门最低工资的员工姓名
    SELECT deptno,count(empno),max(sal),min(sal)
    FROM emp
    GROUP BY deptno;

    
    

    SELECT dname,t.c,t.ma,t.mi,ename
    FROM dept,emp,(SELECT deptno,count(empno) c,max(sal) ma,min(sal) mi
    FROM emp
    GROUP BY deptno) t
    WHERE dept.deptno=emp.deptno and emp.deptno=t.deptno and sal=t.mi;

    
    

    1.查询比自己职位平均工资高的员工姓名、职位,部门名称,职位平均工资
    SELECT JOB,avg(sal)
    FROM emp
    GROUP BY JOB;

    
    

    SELECT ename,emp.JOB,dname,sal,t.a
    FROM emp,dept,(SELECT JOB,avg(sal) a
    FROM emp
    GROUP BY JOB) t
    WHERE emp.deptno=dept.deptno and emp.job=t.job and sal>t.a;

    
    

    2.查询职位和经理同员工SCOTT或BLAKE完全相同的员工姓名、职位,不包括SCOOT和BLAKE本人。
    SELECT ename,job
    FROM emp
    WHERE (JOB,mgr) IN (SELECT JOB,mgr FROM emp WHERE upper(ename) IN('SCOTT','BLAKE')) AND upper(ename) NOT IN('SCOTT','BLAKE');

    
    

    3.查询不是经理的员工姓名
    SELECT ename
    FROM emp
    WHERE empno not in(SELECT distinct mgr FROM emp where mgr is not null);

    
    

    四、分页查询
    1、rownum:伪列:从1开始递增
    ---查询emp表中的前5行记录
    SELECT *
    FROM emp
    WHERE rownum<=5;

    
    

    rownum在做比较运算时,只能使用<,<=,不能使用>,>=

    
    

    ----查询emp表中5~10条记录
    SELECT rownum r,emp.* FROM emp;

    
    

    SELECT rownum,t.*
    FROM (SELECT ROWNUM r,emp.* FROM emp) t
    WHERE t.r between 5 and 10;

    
    

    ---查询emp表中的最后5条记录
    SELECT rownum,t.*
    FROM (SELECT ROWNUM r,emp.* FROM emp) t
    WHERE t.r>(select count(empno) from emp)-5;

    
    

    ---每页显示3条记录,查询第3页的员工信息
    SELECT rownum,t.*
    FROM (SELECT ROWNUM r,emp.* FROM emp) t
    WHERE t.r>(3-1)*3 and t.r<=3*3;

    
    

    ---每页显示3条记录,查询第3页和第5页的员工信息
    SELECT rownum,t.*
    FROM (SELECT ROWNUM r,emp.* FROM emp) t
    WHERE t.r>(3-1)*3 and t.r<=3*3 or t.r>(5-1)*3 and t.r<=5*3;

    
    

    2、TOPN
    ---查询工资最高的员工信息
    SELECT * FROM EMP ORDER BY sal desc;

    
    

    SELECT *
    FROM (SELECT * FROM EMP ORDER BY sal DESC) t
    WHERE rownum<=1;

    
    

    ---查询工资最高的前5位的员工信息
    SELECT *
    FROM (SELECT * FROM EMP ORDER BY sal DESC) t
    WHERE rownum<=5;

    
    
    年轻人能为世界年轻人能为世界做些什么
  • 相关阅读:
    使用JS对字符串进行MD5加密
    awk 控制语句if-else
    nginx日志切割
    Nginx日志监控工具
    运维小工具
    shell脚本2
    nginx优化方案
    centos7修复grub2
    Centos7的引导顺序
    如何同时运行两个tomcat?
  • 原文地址:https://www.cnblogs.com/twinkle-star/p/9287048.html
Copyright © 2020-2023  润新知