Oracle 课堂2

 6.显示能挣得奖金的雇员的姓名、工资、奖金,并以工资和奖金降序排列。
select ename,sal,comm
from emp
WHERE comm>0
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,'D');

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

8.显示姓名中两次出现字母L并且在30部门工作或者其管理员编号是7782的雇员的姓名。
select ename
FROM emp
where ename like '%L%L%'


4.    编写一个以下面的形式输出的查询:
<employee name> earns <salary> monthly but wants <3 times salary>.
列标题为Dream Salaries。

SELECT '<employee ' || ename || '> earns <' || sal || '> monthly but wants <' || 3*sal || '>.' "Dream Salaries"
from emp;

SELECT 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),一个指示符代表一百美元,并以工资数额降序排列。
 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
WHERE emp.deptno(+)=dept.deptno;

SELECT *
FROM emp,dept
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;

猜你喜欢

转载自blog.csdn.net/yuan2yue/article/details/80994921