您的位置:首页 > 数据库 > Oracle

Oracle Day3 多行函数、多表查询

2016-03-16 20:28 211 查看
1.多行函数

Sum avg max min count

组函数具有滤空的作用(添加nvl屏蔽该功能)

分组groupby

多行分组

分组过滤

where 和分组过滤的区别(having)

分组的增强(rollup)

  break on deptno skip 2;

  break on null;

SQL>  -- 计算一下每一个月要发多少工资,不含奖金
SQL> select sum(sal) from emp;

SUM(SAL)
----------
29025

SQL> select sal from emp;

SAL
----------
800
1600
1250
2975
1250
2850
2450
3000
5000
1500
1100

SAL
----------
950
3000
1300

已选择14行。

SQL> -- 计算一下每年发的奖金的和
SQL> select sum(comm) from emp;

SUM(COMM)
----------
2200

SQL> select comm from emp;

COMM
----------

300
500

1400

0

COMM
----------

已选择14行。

SQL> -- 多行函数自动虑空
SQL> -- 计算一下公司的平均工资
SQL> select sum(sal)/count(*) from emp;

SUM(SAL)/COUNT(*)
-----------------
2073.21429

SQL> select sum(sal)/count(sal)) from emp;
select sum(sal)/count(sal)) from emp
*
第 1 行出现错误:
ORA-00923: 未找到要求的 FROM 关键字

SQL> select sum(sal)/count(sal) from emp;

SUM(SAL)/COUNT(SAL)
-------------------
2073.21429

SQL> select avg(sal) from emp;

AVG(SAL)
----------
2073.21429

SQL> -- 计算一下平均奖金
SQL> select sum(comm)/count(*) from emp;

SUM(COMM)/COUNT(*)
------------------
157.142857

SQL> select sum(comm)/count(comm) from emp;

SUM(COMM)/COUNT(COMM)
---------------------
550     错误方法

SQL> select avg(comm) from emp;

AVG(COMM)
----------
550                错误方法

SQL>  -- 多行函数的虑空并不是在所有的场合都适用,如果你不希望他的虑空起作用你可以采用函数的嵌套来屏蔽该功能
SQL> select sum(comm)/count(*),avg(nvl(comm,0)) from emp;

SUM(COMM)/COUNT(*) AVG(NVL(COMM,0))
------------------ ----------------
157.142857       157.142857

SQL> -- 查询工资最高和最低的员工信息
SQL> select max(sal),min(sal) from emp;

MAX(SAL)   MIN(SAL)
---------- ----------
5000        800

SQL> select max(comm),min(comm) from emp;

MAX(COMM)  MIN(COMM)
---------- ----------
1400          0

SQL> -- 分组
SQL> -- 求每一个部门的工资总和 和平均工资
SQL> select deptno,sum(sal),avg(sal)
2  from emp
3  group by deptno;

DEPTNO   SUM(SAL)   AVG(SAL)
---------- ---------- ----------
30       9400 1566.66667
20      10875       2175
10       8750 2916.66667

SQL> -- 统计部门的平均工资,部门号,岗位
SQL> select deptno,avg(sal),job
2  from emp
3  group by deptno,job;

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------
20        950 CLERK
30       1400 SALESMAN
20       2975 MANAGER
30        950 CLERK
10       5000 PRESIDENT
30       2850 MANAGER
10       1300 CLERK
10       2450 MANAGER
20       3000 ANALYST

已选择9行。

SQL>  -- group by 后面必须要跟select后面没有在多行函数里面的字段
SQL> -- 分组函数的过滤
SQL> -- 统计部门号为20的部门下的所有职位的平均工资
SQL> select deptno,avg(sal),job
2  from emp
3  where deptno=20
4  group by deptno,job;

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------
20        950 CLERK
20       2975 MANAGER
20       3000 ANALYST

SQL> select deptno,avga(sal),job
2  from emp
3  group by deptno,job
4  having deptno=20;
select deptno,avga(sal),job
*
第 1 行出现错误:
ORA-00904: "AVGA": 标识符无效

SQL> c /avga(sal)/avg(sal);
1* select deptno,avg(sal),job
SQL> /

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------
20        950 CLERK
20       2975 MANAGER
20       3000 ANALYST

SQL> -- 统计平均工资大于2000的部门
SQL> select deptno,avg(sal)
2  from emp
3  where avg(sal) >2000
4  group by deptno,job;
where avg(sal) >2000
*
第 3 行出现错误:
ORA-00934: 此处不允许使用分组函数

SQL> select deptno,avg(sal)
2  from emp
3  group by deptno
4  having avg(sal)>2000;

DEPTNO   AVG(SAL)
---------- ----------
20       2175
10 2916.66667

SQL> --1. where和having都可以用来做条件的过滤操作,但是where后面不能跟分组函数,having后面可以跟分组函数
SQL> -- 2 尽量使用where 因为他的效率更高
SQL> select deptno,job,sum(sal)
2  from emp
3  group by rollup(deptno,job);

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
10 CLERK                    1300
10 MANAGER                  2450
10 PRESIDENT                5000
10                          8750
20 CLERK                    1900
20 ANALYST                  6000
20 MANAGER                  2975
20                         10875
30 CLERK                     950
30 MANAGER                  2850
30 SALESMAN                 5600

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
30                          9400
29025

已选择13行。

SQL> break on deptno skip 2;
SQL> /

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
10 CLERK                    1300
MANAGER                  2450
PRESIDENT                5000
8750

20 CLERK                    1900
ANALYST                  6000
MANAGER                  2975
10875

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------

30 CLERK                     950
MANAGER                  2850
SALESMAN                 5600
9400

29025

已选择13行。

SQL> --break on deptno skip 2;去除deptno后相同的no,并空两行;
SQL> break on null;
SQL> /

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
10 CLERK                    1300
10 MANAGER                  2450
10 PRESIDENT                5000
10                          8750
20 CLERK                    1900
20 ANALYST                  6000
20 MANAGER                  2975
20                         10875
30 CLERK                     950
30 MANAGER                  2850
30 SALESMAN                 5600

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
30                          9400
29025

已选择13行。

SQL> break on deptno skip 3;
SQL> /

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
10 CLERK                    1300
MANAGER                  2450
PRESIDENT                5000
8750

20 CLERK                    1900
ANALYST                  6000
MANAGER                  2975
10875

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------

30 CLERK                     950
MANAGER                  2850
SALESMAN                 5600
9400

29025

已选择13行。

SQL> select sum(sal) from emp;

SUM(SAL)
----------
29025

SQL> select sum(comm) from emp;

SUM(COMM)
----------
2200

SQL> select sum(sal)/count(*) from emp;

SUM(SAL)/COUNT(*)
-----------------
2073.21429

SQL> select sum(sal)/count(sal) from emp;

SUM(SAL)/COUNT(SAL)
-------------------
2073.21429

SQL> select avg(sal) from emp;

AVG(SAL)
----------
2073.21429

SQL> select max(sal),min(sal) from emp;

MAX(SAL)   MIN(SAL)
---------- ----------
5000        800

SQL> select max(comm),min(comm) from emp;

MAX(COMM)  MIN(COMM)
---------- ----------
1400          0

SQL> select deptno,sum(sal),avg(sal)
2  from emp
3  group by deptno;d
4  ;
group by deptno;d
*
第 3 行出现错误:
ORA-00911: 无效字符

SQL> select deptno,sum(sal),avg(sal)
2  from emp
3  group by deptno;

DEPTNO   SUM(SAL)   AVG(SAL)
---------- ---------- ----------
30       9400 1566.66667

20      10875       2175

10       8750 2916.66667

SQL> select deptno,avg(sal),job
2  from emp
3  group by deptno,job;

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------
20        950 CLERK

30       1400 SALESMAN

20       2975 MANAGER

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------

30        950 CLERK

10       5000 PRESIDENT

30       2850 MANAGER

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------

10       1300 CLERK
2450 MANAGER

20       3000 ANALYST

已选择9行。

SQL> select deptno,avg(sal),job
2  from emp
3  where deptno=20
4  group by deptno,job;

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------
20        950 CLERK
2975 MANAGER
3000 ANALYST

SQL> select deptno,avg(sal),job
2  from emp
3  group by deotno,job
4  having deptno=20;
group by deotno,job
*
第 3 行出现错误:
ORA-00904: "DEOTNO": 标识符无效

SQL> c /deotno/deptno;
3* group by deptno,job
SQL> /

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------
20        950 CLERK
2975 MANAGER
3000 ANALYST

SQL> select deptno,avg(sal),job
2  from emp
3  group by deptno,job
4  having avg(sal)>2000;

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------
20       2975 MANAGER

10       5000 PRESIDENT

30       2850 MANAGER

DEPTNO   AVG(SAL) JOB
---------- ---------- ------------------

10       2450 MANAGER

20       3000 ANALYST

SQL> select deptno,job,sum(sal)
2  from emp
3  group by rollup(deptno,job);

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
10 CLERK                    1300
MANAGER                  2450
PRESIDENT                5000
8750

20 CLERK                    1900
ANALYST                  6000
MANAGER                  2975
10875

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------

30 CLERK                     950
MANAGER                  2850
SALESMAN                 5600
9400

29025

已选择13行。

SQL> break on null;
SQL> /

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
10 CLERK                    1300
10 MANAGER                  2450
10 PRESIDENT                5000
10                          8750
20 CLERK                    1900
20 ANALYST                  6000
20 MANAGER                  2975
20                         10875
30 CLERK                     950
30 MANAGER                  2850
30 SALESMAN                 5600

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
30                          9400
29025

已选择13行。

SQL> break on deptno skip 2;
SQL> /

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------
10 CLERK                    1300
MANAGER                  2450
PRESIDENT                5000
8750

20 CLERK                    1900
ANALYST                  6000
MANAGER                  2975
10875

DEPTNO JOB                  SUM(SAL)
---------- ------------------ ----------

30 CLERK                     950
MANAGER                  2850
SALESMAN                 5600
9400

29025

已选择13行。

SQL> spool off;


  2.多表查询

     1)笛卡尔集

     2)等值连接

     3)非等值连接

     4)外连接

     5)内连接

     6)层次查询(只能有一张表 connect by prior empno = mgr start width empno = 7839)

  

SQL> --  查询所有部门的信息和部门下的所有员工信息
SQL> select e.empno,e.ename,job,d.deptno,d.dname
2  from emp e,dept d
3  where e.deptno=d.deptno;

EMPNO ENAME                          JOB                    DEPTNO DNAME
---------- ------------------------------ ------------------ ---------- ----------------------------
7369 SMITH                          CLERK                      20 RESEARCH

7499 ALLEN                          SALESMAN                   30 SALES
7521 WARD                           SALESMAN                      SALES

7566 JONES                          MANAGER                    20 RESEARCH

7654 MARTIN                         SALESMAN                   30 SALES

EMPNO ENAME                          JOB                    DEPTNO DNAME
---------- ------------------------------ ------------------ ---------- ----------------------------
7698 BLAKE                          MANAGER                    30 SALES

7782 CLARK                          MANAGER                    10 ACCOUNTING

7788 SCOTT                          ANALYST                    20 RESEARCH

7839 KING                           PRESIDENT                  10 ACCOUNTING

EMPNO ENAME                          JOB                    DEPTNO DNAME
---------- ------------------------------ ------------------ ---------- ----------------------------

7844 TURNER                         SALESMAN                   30 SALES

7876 ADAMS                          CLERK                      20 RESEARCH

7900 JAMES                          CLERK                      30 SALES

7902 FORD                           ANALYST                    20 RESEARCH

EMPNO ENAME                          JOB                    DEPTNO DNAME
---------- ------------------------------ ------------------ ---------- ----------------------------

7934 MILLER                         CLERK                      10 ACCOUNTING

已选择14行。

SQL> select * from tab;

TNAME                                                        TABTYPE         CLUSTERID
------------------------------------------------------------ -------------- ----------
DEPT                                                         TABLE
EMP                                                          TABLE
BONUS                                                        TABLE
SALGRADE                                                     TABLE

SQL> select *from salgrade;

GRADE      LOSAL      HISAL
---------- ---------- ----------
1        700       1200
2       1201       1400
3       1401       2000
4       2001       3000
5       3001       9999

SQL>  -- 查询员工信息和员工的工资级别
SQL> select e.empno,e.sal,s.grade,s.losal,s.hisal
2  from emp e,salgrade s
3  where e.sal between s.losal and s.hisal;

EMPNO        SAL      GRADE      LOSAL      HISAL
---------- ---------- ---------- ---------- ----------
7369        800          1        700       1200
7900        950          1        700       1200
7876       1100          1        700       1200
7521       1250          2       1201       1400
7654       1250          2       1201       1400
7934       1300          2       1201       1400
7844       1500          3       1401       2000
7499       1600          3       1401       2000
7782       2450          4       2001       3000
7698       2850          4       2001       3000
7566       2975          4       2001       3000

EMPNO        SAL      GRADE      LOSAL      HISAL
---------- ---------- ---------- ---------- ----------
7788       3000          4       2001       3000
7902       3000          4       2001       3000
7839       5000          5       3001       9999

已选择14行。

SQL> -- 不等值连接
SQL> -- 外连接
SQL>  -- 统计每一个部门的人数
SQL> -- 显示部门号 部门名称 部门人数
SQL> select e.deptno,d.dname,count(*)
2  from emp e,dept d
3  where e.deptno=d.deptno
4  group by e.deptno,d.dname;

DEPTNO DNAME                          COUNT(*)
---------- ---------------------------- ----------
10 ACCOUNTING                            3

20 RESEARCH                              5

30 SALES                                 6

SQL> select * from dept;

DEPTNO DNAME                        LOC
---------- ---------------------------- --------------------------
10 ACCOUNTING                   NEW YORK

20 RESEARCH                     DALLAS

30 SALES                        CHICAGO

40 OPERATIONS                   BOSTON

SQL>  /*
SQL>
SQL> 外连接:分类左外连接和右外连接
SQL> 左外连接:  where e.deptno = d.deptno 不成立的时候,无论右边是否有数据与之对应,左边的都要显示
SQL>            where e.deptno = d.depton(+)
SQL> 右外连接:  where e.deptno = d.deptno 不成立的时候,无论左边表是否有数据与之对应,右边表都会显示
SQL>            where e.deptno(+) = d.deptno;
SQL> */
SQL> select d.deptno,d.dname,count(e.empno)
2  from emp e,dept d
3  where e.deptno(+)=d.deptno
4  group by d.deptno,d.deptname;
group by d.deptno,d.deptname
*
第 4 行出现错误:
ORA-00904: "D"."DEPTNAME": 标识符无效

SQL> c /d.deptname/d.dname;
4* group by d.deptno,d.dname
SQL> /

DEPTNO DNAME                        COUNT(E.EMPNO)
---------- ---------------------------- --------------
10 ACCOUNTING                                3

40 OPERATIONS                                0

20 RESEARCH                                  5

30 SALES                                     6

SQL> select d.deptno,d.dname,count(e.empno)
2  from emp e,dept d
3  where e.deptno=d.deptno(+)
4  group by d.deptno,d.dname;

DEPTNO DNAME                        COUNT(E.EMPNO)
---------- ---------------------------- --------------
10 ACCOUNTING                                3

20 RESEARCH                                  5

30 SALES                                     6

SQL> select e.ename 领导名字,e.empno 领导id,p.ename 员工名字,p.empno 员工id
2  from emp e,emp p
3  where e.ename=p.mgr;
where e.ename=p.mgr
*
第 3 行出现错误:
ORA-01722: 无效数字

SQL> c /e.ename/e.empno;
3* where e.empno=p.mgr
SQL> /

领导名字                 领导ID 员工名字                 员工ID
-------------------- ---------- -------------------- ----------
FORD                       7902 SMITH                      7369
BLAKE                      7698 ALLEN                      7499
BLAKE                      7698 WARD                       7521
KING                       7839 JONES                      7566
BLAKE                      7698 MARTIN                     7654
KING                       7839 BLAKE                      7698
KING                       7839 CLARK                      7782
JONES                      7566 SCOTT                      7788
BLAKE                      7698 TURNER                     7844
SCOTT                      7788 ADAMS                      7876
BLAKE                      7698 JAMES                      7900

领导名字                 领导ID 员工名字                 员工ID
-------------------- ---------- -------------------- ----------
JONES                      7566 FORD                       7902
CLARK                      7782 MILLER                     7934

已选择13行。

SQL> select count(*) from emp e,emp p
2  where e.empno=p.mgr;

COUNT(*)
----------
13

SQL> select count(*) from emp e,emp p;

COUNT(*)
----------
196

SQL> -- 内连接只能做数据量小的表,对于大表用层次查询
SQL>  -- 层次查询
SQL> select ename 领导名字,empno 领导id
2  from emp
3  connect by prior empno=mgr
4  start with mgr is null;

领导名字                 领导ID
-------------------- ----------
KING                       7839
JONES                      7566
SCOTT                      7788
ADAMS                      7876
FORD                       7902
SMITH                      7369
BLAKE                      7698
ALLEN                      7499
WARD                       7521
MARTIN                     7654
TURNER                     7844

领导名字                 领导ID
-------------------- ----------
JAMES                      7900
CLARK                      7782
MILLER                     7934

已选择14行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: