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;
Oracle作业5——多表查询、子查询的更多相关文章
- oracle 基础SQL语句 多表查询 子查询 分页查询 合并查询 分组查询 group by having order by
select语句学习 . 创建表 create table user(user varchar2(20), id int); . 查看执行某条命令花费的时间 set timing on: . 查看表的 ...
- sql:除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询
执行sql语句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date ...
- Python-select 关键字 多表查询 子查询
sql 最核心的查询语句!!!! 增删改 单表查询 select语句的完整写法 关键字的书写顺序 执行顺序 多表查询 笛卡尔积 内连接 左外连接 右外连接 全外连接 通过合并左外连接和右外连接 子查询 ...
- ORDER BY 子句在视 图、内联函数、派生表、子查询和公用表表达式中无效
SQL语句: select * from (select distinct t2.issue,cashmoney from (select distinct issue from lot_gamepa ...
- [转]sql:除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询
执行sql语句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date ...
- [sql Server]除非另外还指定了TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效
今天遇到一个奇怪的问题,项目突然要从mysql切换到sql server数据库,包含order by 子句的嵌套子查询报错. 示例:select top 10 name,age,sex from ( ...
- ylb: SQL表的高级查询-子查询
ylbtech-SQL Server: SQL Server- SQL表的高级查询-子查询 SQL Server 表的高级查询-子查询. 1,ylb:表的高级查询-子查询返回顶部 --======== ...
- Oracle的查询-子查询
--子查询 --子查询返回一个值 --查询出工资和scott一样的员工信息 select * from emp where sal in (select sal from emp where enam ...
- mysql中【update/Delete】update中无法用基于被更新表的子查询,You can't specify target table 'test1' for update in FROM clause.
关键词:mysql update,mysql delete update中无法用基于被更新表的子查询,You can't specify target table 'test1' for update ...
- 【数据库】SQL经典面试题 - 数据库查询 - 子查询应用二
上节课我们通过子查询,完成了查询的最高分学生的需求,今天我们来学习子查询的分类,以及通过子查询来完成工作中经常遇到一些个性化需求. 子查询概念: 一个SELECT语句嵌套在另一个SELECT语句中,子 ...
随机推荐
- vue-cli脚手架项目实例
看完了配置,接下来通过一个实例,更清晰地了解这些文件之间的联系,顺带练习练习vue相关知识. 1.安装 打开命令行控制器,系统自带cmd或者git bash等都可以,按照顺序输入如下指令,耐心等待每一 ...
- vue-cli脚手架之其他文件解释
好了,脚手架目录中重要的文件基本都介绍了,但还有一个不太注意到的文件没有解释,这里也说明一下. config文件夹下的index.js,作用是不同开发环境下的参数配置(可选项很多,生产环境.开发环境. ...
- 原生js制作标题与内容保持4行的效果
在制作网页或移动端有时会用到一个效果,类似文章标题和文章描述的排列总是保持一样的行数,要么标题总是一行,多出的省略,要么标题内容1:3或2:2或3:1这样,今天练习这样的效果. 实现的原理:给标题和内 ...
- Java Struts2 (一)
一.Struts2简介 1.Struts2概述 Struts2是Apache发行的MVC开源框架.注意:它只是表现层(MVC)框架. 2.Struts2的来历 Struts1:也是apache开发的一 ...
- 十四、css动画基础知识
引用动画的方式: 1.轻量动画: cubic-bezier(0.165, 0.840, 0.440, 1.000);//加上贝塞尔曲线使动画运动起来更加平滑 2..scrollNews,.m-tr ...
- Qt QDialog将窗体变为顶层窗体(activateWindow(); 和 raise() )
m_pLoginDlg->hide(); m_pLoginDlg->activateWindow(); //m_pLoginDlg->raise(); m_pLoginDlg-> ...
- css display属性详解
css display属性在对css做layout设计时非常重要,它的值有以下几种: Value Description Play it inline Default value. Displays ...
- C++ inheritance examples
1.C++继承经典例子 #include <iostream> using namespace std; class Base { private: int b_number; publi ...
- MySQL5.7二进制安装
MySQL-5.7.14从零开始-安装 首先我们要选择下载MySQL的版本: 登录官方网站下载:https://dev.mysql.com/downloads/mysql/ 下面我们选择5.7.14的 ...
- 代码分析工具推荐Understand
之前看ogitor ,第一次看到那么多代码~~不知道从哪里下手,而且好多东西都不会Ogre什么的都不是很清楚,对ogitor的代码结构的了解就更不用提了.晕头转向的 不知道从哪里下手,一点点的看起来好 ...