Oracle作业5——多表查询、子查询
一、基础练习:
1.查询和scott相同部门的员工姓名ename和雇用日期hiredate
SELECT ENAME,HIREDATE FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM EMP WHERE ENAME='SCOTT');
2.查询在部门的loc为NEW YORK的部门工作的员工的员工姓名ename,部门名称dname和岗位名称job
SELECT E.ENAME,D.DNAME,E.JOB,D.LOC FROM EMP E,DEPT D WHERE E.DEPTNO=D.DEPTNO AND D.LOC='NEW YORK';
3.查询上司是king的员工姓名(ename)和工资(sal)
SELECT ENAME,SAL FROM EMP WHERE MGR=(SELECT EMPNO FROM EMP WHERE ENAME='KING');
4.查询与姓名中包含字母U的员工在相同部门的员工信息
SELECT * FROM EMP WHERE DEPTNO IN(SELECT DEPTNO FROM EMP WHERE ENAME LIKE '%U%');
5.查询所有雇员姓名和部门名称(使用left join,inner join, right join)
SELECT E.ENAME,D.DNAME FROM EMP E INNER JOIN DEPT D ON E.DEPTNO=D.DEPTNO; SELECT E.ENAME,D.DNAME FROM EMP E LEFT JOIN DEPT D ON E.DEPTNO=D.DEPTNO; SELECT E.ENAME,D.DNAME FROM DEPT D RIGHT JOIN EMP E ON E.DEPTNO=D.DEPTNO;
6.显示每个员工的员工姓名、部门名称、职务、工资、和工资等级信息(使用left join,inner join, right join)
SELECT E.ENAME,D.DNAME,E.JOB,E.SAL,S.GRADE FROM EMP E INNER JOIN DEPT D ON E.DEPTNO=D.DEPTNO INNER JOIN SALGRADE S ON E.SAL BETWEEN S.LOSAL AND S.HISAL;SELECT E.ENAME,D.DNAME,E.JOB,E.SAL,S.GRADE FROM EMP E LEFT JOIN DEPT D ON E.DEPTNO=D.DEPTNO LEFT JOIN SALGRADE S ON E.SAL BETWEEN S.LOSAL AND S.HISAL;SELECT E.ENAME,D.DNAME,E.JOB,E.SAL,S.GRADE FROM DEPT D RIGHT JOIN EMP E ON E.DEPTNO=D.DEPTNO RIGHT JOIN SALGRADE S ON E.SAL BETWEEN S.LOSAL AND S.HISAL;
二、综合练习
1.取得每个部门最高薪水的人员名称2.列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称
--使用相关子查询 SELECT EMPNO,ENAME,SAL,DEPTNO FROM EMP E WHERE E.SAL=(SELECT MAX(SAL) FROM EMP M WHERE M.DEPTNO=E.DEPTNO) ORDER BY DEPTNO; --使用多表连接查询(渔舟唱晚同学的) SELECT EMPNO,ENAME,SAL,DEPTNO FROM EMP Q, (SELECT E.DEPTNO 部门, MAX(E.SAL) 最高薪资 FROM EMP E GROUP BY E.DEPTNO) R WHERE R.部门 = Q.DEPTNO AND Q.SAL = R.最高薪资 ORDER BY Q.DEPTNO; --使用DENSE_RANK()函数结合ORDER BY SELECT * FROM(SELECT EMPNO,ENAME,SAL,DEPTNO,DENSE_RANK() OVER(PARTITION BY DEPTNO ORDER BY SAL DESC)RN FROM EMP) WHERE RN=1 ORDER BY DEPTNO; --使用IN子查询(有BUG) SELECT EMPNO,ENAME,DEPTNO,SAL FROM EMP WHERE SAL IN(SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO) ORDER BY DEPTNO;
--测试上面的IN子查询BUG:发现10部门的NulluN也显示出来了,但其并非10部门最高工资,10部门最高工资为5000 INSERT INTO EMP(EMPNO,ENAME,DEPTNO,SAL) VALUES(1015,'NulluN',10,3000); SELECT EMPNO,ENAME,DEPTNO,SAL FROM EMP WHERE SAL IN(SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO) ORDER BY DEPTNO;
2.列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称
--左自连接和多表查询 SELECT E.EMPNO 员工编号,E.ENAME 员工姓名,M.ENAME 主管姓名,E.HIREDATE 员工受雇日期, M.HIREDATE 上级雇用日期,D.DNAME 部门名称 FROM EMP E,EMP M,DEPT D WHERE M.EMPNO(+)=E.MGR AND E.HIREDATE<M.HIREDATE AND E.DEPTNO=D.DEPTNO ORDER BY E.EMPNO;
--相关子查询和多表查询 SELECT E.EMPNO,E.ENAME,D.DNAME FROM EMP E,DEPT D WHERE E.HIREDATE <(SELECT HIREDATE FROM EMP M WHERE M.EMPNO=E.MGR) AND E.DEPTNO=D.DEPTNO ORDER BY E.EMPNO;
3.列出所有"CLERK"(办事员)的姓名及其部门名称,部门的人数
思路:1.先查询JOB为CLERK的所有部门编号,将该子查询结果命名为A;2.再从EMP表查询与A查询中部门编号相同的员工所在的部门人数,这一步的查询结果命名为B;3.最后从EMP表、DEPT表和B查询中进行多表查询获取JOB为CLERK的所有员工的姓名、部门名称和所在部门人数。
SELECT E.ENAME,D.DNAME,T.部门人数,E.JOB FROM EMP E,DEPT D,(SELECT DEPTNO,COUNT(1) 部门人数 FROM EMP WHERE DEPTNO IN( SELECT DISTINCT DEPTNO FROM EMP WHERE JOB='CLERK') GROUP BY DEPTNO)T WHERE E.DEPTNO=D.DEPTNO AND E.JOB='CLERK' AND T.DEPTNO=E.DEPTNO;
4.列出与"SCOTT"从事相同工作的所有员工及部门名称
SELECT E.*,D.DNAME FROM EMP E,DEPT D WHERE E.JOB=(SELECT JOB FROM EMP WHERE ENAME='SCOTT') AND E.DEPTNO=D.DEPTNO;
5.查出某个员工的上级主管,并要求出这些主管中的薪水超过3000
SELECT E.EMPNO 员工编号,E.ENAME 员工姓名,M.ENAME 主管姓名,M.SAL 主管工资 FROM EMP E,EMP M WHERE M.EMPNO(+)=E.MGR AND M.SAL>3000;
6.找出部门10中所有经理(MANAGER)和部门20中所有办事员(CLERK)的详细资料
SELECT E.*,D.DNAME,D.LOC,S.* FROM EMP E,DEPT D,SALGRADE S WHERE E.DEPTNO=D.DEPTNO AND E.SAL BETWEEN S.LOSAL AND S.HISAL AND (E.DEPTNO=10 AND E.JOB='MANAGER' OR E.DEPTNO=20 AND E.JOB='CLERK'); --注意:E.DEPTNO=10 AND E.JOB='MANAGER' OR E.DEPTNO=20 AND E.JOB='CLERK' 要用括号括起来,不然会与前面的AND条件混淆造成错误!
7.找出早于12年前受雇的员工. 并且按受雇年份倒序排序
思路一:用MONTHS_BETWEEN比较当前系统时间和受雇日期之前相差的月份,然后除以12,如果值大于12,则是早于12前受雇的员工。
--有错误的语句 SELECT E.*,TO_CHAR(HIREDATE,'YYYY') 受雇年份,ROUND((MONTHS_BETWEEN(SYSDATE,HIREDATE)/12),2) 受雇年限 FROM EMP E WHERE 受雇年限>12 ORDER BY 受雇年份 DESC; /*为什么“受雇年限”会是无效的标识符呢?因为SELECT语句在WHERE语句后面才执行,而列的别名(受雇年限)是在SELECT时才生成的,故在WHERE子句中看不到这个别名(受雇年限),自然无法引用这个别名了。*/--排错后的正确语句 SELECT E.*,TO_CHAR(HIREDATE,'YYYY') 受雇年份,ROUND((MONTHS_BETWEEN(SYSDATE,HIREDATE)/12),2) 受雇年限 FROM EMP E WHERE (MONTHS_BETWEEN(SYSDATE,HIREDATE)/12)>12 ORDER BY 受雇年份 DESC;
思路二:用ADD_MONTHS判断,(受雇日期+12*12)得出的日期如果小于当前系统时间,则是早于12前受雇的员工。
SELECT E.*,TO_CHAR(HIREDATE,'YYYY') 受雇年份,ADD_MONTHS(HIREDATE,12*12) 受雇十二周年日,ROUND((MONTHS_BETWEEN(SYSDATE,HIREDATE)/12),2) 受雇年限 FROM EMP E WHERE ADD_MONTHS(HIREDATE,12*12)<SYSDATE ORDER BY 受雇年份 DESC;--注意:离当前日期越远的日期越小,反之,离当前日期越近的日期越大。
8.列出从事同一种工作但属于不同部门的员工的一种组合
--不算完美但算比较接近题意的SQL语句 SELECT DISTINCT E.EMPNO,E.ENAME,E.JOB,E.DEPTNO FROM EMP E,EMP P WHERE E.DEPTNO!=P.DEPTNO AND E.JOB=P.JOB ORDER BY JOB,DEPTNO; --其它两种不等于的写法 SELECT DISTINCT E.EMPNO,E.ENAME,E.JOB,E.DEPTNO FROM EMP E,EMP P WHERE E.DEPTNO<>P.DEPTNO AND E.JOB=P.JOB ORDER BY JOB,DEPTNO; SELECT DISTINCT E.EMPNO,E.ENAME,E.JOB,E.DEPTNO FROM EMP E,EMP P WHERE E.DEPTNO^=P.DEPTNO AND E.JOB=P.JOB ORDER BY JOB,DEPTNO; /*精妙之处:使用DISTINCT!如果不使用DISTINCT,查询结果会出现很多一样的重复数据!*/
分析:为什么说上面的SQL语句不算完美呢?因为从上图可看出JOB为CLERK,且DEPTNO=20的记录有两条,即分别是第2和第3条查询记录,这就与题目要求的“从事同一种工作但属于不同部门的员工”不一致了,故最理想的查询结果应该如下:
9.查询有奖金的所有员工的姓名、奖金以及所在部门名称
--如果奖金等于0也算有奖金,那如下实现: SELECT ENAME,COMM,DNAME FROM EMP E,DEPT D WHERE COMM IS NOT NULL AND E.DEPTNO=D.DEPTNO;
--如果奖金等于0不算有奖金,则如下实现: SELECT ENAME,COMM,DNAME FROM EMP E,DEPT D WHERE COMM IS NOT NULL AND COMM<>0 AND E.DEPTNO=D.DEPTNO;
10.给任职日期超过25年的员工加薪10%
SELECT E.ENAME,E.SAL 原薪水,E.SAL*1.1 加薪后薪水,ROUND((MONTHS_BETWEEN(SYSDATE,HIREDATE)/12),2) 受雇年限 FROM EMP E WHERE (MONTHS_BETWEEN(SYSDATE,HIREDATE)/12)>25;
转载于:https://www.cnblogs.com/6nullun6/p/9813805.html
Oracle作业5——多表查询、子查询相关推荐
- 数据库 day60,61 Oracle入门,单行函数,多表查询,子查询,事物处理,约束,rownum分页,视图,序列,索引
1. oracle介绍 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的 ...
- 怎样学好Oracle子查询,Oracle学习(六):子查询
Oracle学习(6):子查询 子查询 为何要用子查询 SQL> --查询工资比SCOTT高的员工信息 SQL> --1. 知道SCOTT的工资 SQL> select sal fr ...
- oracle sql 转换成 hive sql -子查询转关联查询(三).子查询中嵌套子查询
其他sql格式也在更新中,可直接查看俺的这个系列,要是没有你需要的格式,可在评论或私信我,俺现在一天一看 Oracle转换hive 其他sql格式也在更新中,可直接查看俺的这个系列,要是没有你需要的格 ...
- mySQL学习记录(局域网连接/基础查询/条件查询/常见函数/窗口函数/表连接/子查询/插修删建表)
一些基础概念 DB 数据库 存储数据的容器 DBMS 数据库管理系统 又称数据库软件.产品如mysql/oracle/db2/sqlserver SQL 结构化查询语言 是所有的DBMS都使用的一种D ...
- 除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询...
执行sql语句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date ...
- sql 基础语法 创建数据库和数据表 数据增删改查 分组查询 子查询回顾
参考链接: SQL教程 MySQL教程 一.创建数据库语法 --用master数据库 use master --判断数据库是否存在,若存在则删除 if exists (select * from sy ...
- MySQL数据库多表查询,子查询
写博客的第四天,今天来点数据库的操作,温故而知新,在前进的路上,多看看自己曾经走过的路,不要忘了自己是怎么一步一步走过来的,对于前方未知的道路,不要轻言放弃. 今天的内容全部是MySQL里面的语句,基 ...
- (解决)除非另外还指定了 TOP、OFFSET 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效Mybatis-plus 默认分页功能报错
(解决)除非另外还指定了 TOP.OFFSET 或 FOR XML,否则,ORDER BY 子句在视图.内联函数.派生表.子查询和公用表表达式中无效Mybatis-plus 默认分页功能报错 我百度了 ...
- MySQL核心查询-排序 分组 聚合 多表查询 合并查询 子查询
目录 一.单表查询 排序 聚合函数 分组 limit关键字 二.SQL约束 主键的自增 DELETE和TRUNCATE对自增长的影响 三.多表查询 外键约束 删除外键约束 多表查询的分类 内连接查询 ...
- mysql 子表_MySQL子查询,派生表和通用表达式
一:子查询 1.介绍 在另一个查询(外部查询)中嵌套另一个查询语句(内部查询),并使用内部查询的结果值作为外部查询条件. 2.子查询在where中 SELECT customerNumber, che ...
最新文章
- 【特征匹配】ORB原理与源码解析
- SaltStack:Salt SSH
- Android Activtity Security
- k8s pod和service的关系及常用service类型:ClusterIP/NodePort/LoadBalancer
- NSCoding和NSCopy
- Spring开发环境搭建和第一个示例程序
- shell判定一个变量等于-n_Shell test命令:条件判断,检查某条件是否成立
- 面试题系列(9):对前端界面工程师这个职位是怎么样理解的?
- rust大油田分解机_辽河油田曙光采油厂:智慧党建建强战斗堡垒
- 编译原理第三章词法分析知识点思维导图版
- 淘宝x-sign算法demo示例
- HUAWEI 机试题:统计射击比赛成绩
- css修改方框内容,CSS改变checkbox的方框及对勾的粗细
- 尽量使用unity引擎的Random随机数
- java文件乱码_java文件读取出现乱码解决方法
- 2012意大利之行1:从深圳到罗马
- python 保存网页图片到本地
- 直播技术总结(一)流媒体服务器搭建,进行推流
- AcWing蓝桥杯AB组辅导课07、贪心
- 天瑞地安科技集团为你解读2017年平面设计大趋势