oracle数据库学习之初步(2)

本文深入讲解了SQL查询的基础语法及高级用法,包括过滤、排序、分组等操作,同时探讨了不同类型的函数如日期函数、数学函数的应用,以及如何通过多表连接获取所需数据。

过滤和排序数据

基本SQL语句格式如下:
select ….
from table1
where ….
order by ….

//where
1 有关日期格式属性修改 常识
NLS_DATE_FORMAT 的默认格式 DD-MON-RR
select sysdate from dual;
NLS_CURRENCY ¥
SQL> select * from v$nls_parameters;

        PARAMETER                                                        VALUE
        ---------------------------------------------------------------- -------------------------------------------
        ---------
        NLS_LANGUAGE                                                     SIMPLIFIED CHINESE
        NLS_TERRITORY                                                    CHINA
        NLS_CURRENCY                                                     ¥
        NLS_ISO_CURRENCY                                                 CHINA
        NLS_NUMERIC_CHARACTERS                                           .,
        NLS_CALENDAR                                                     GREGORIAN
        NLS_DATE_FORMAT                                                  DD-MON-RR
        NLS_DATE_LANGUAGE                                                SIMPLIFIED CHINESE
        NLS_CHARACTERSET                                                 ZHS16GBK
        NLS_SORT                                                         BINARY
        NLS_TIME_FORMAT                                                  HH.MI.SSXFF AM
        NLS_TIMESTAMP_FORMAT                                             DD-MON-RR HH.MI.SSXFF AM
        NLS_TIME_TZ_FORMAT                                               HH.MI.SSXFF AM TZR
        NLS_TIMESTAMP_TZ_FORMAT                                          DD-MON-RR HH.MI.SSXFF AM TZR
        NLS_DUAL_CURRENCY                                                ¥
        NLS_NCHAR_CHARACTERSET                                           AL16UTF16
        NLS_COMP                                                         BINARY
        NLS_LENGTH_SEMANTICS                                             BYTE
        NLS_NCHAR_CONV_EXCP                                              FALSE

        已选择19行。
 alter session set NLS_DATE_FORMAT='DD-MON-RR';
 alter  session set NLS_DATE_FORMAT='yyyy-mm-dd';

—-查询比81年1月1号 入职晚的员工

          1  select *
          2  from emp
          3* where hiredate > '01-1月 -81'
        SQL> /

             EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
        ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
              7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
              7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
              7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
              7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
              7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
              7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
              7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
              7839 KING       PRESIDENT            17-11月-81           5000                    10
              7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
              7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
              7900 JAMES      CLERK           7698 03-12月-81            950                    30
              7902 FORD       ANALYST         7566 03-12月-81           3000                    20
              7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

        已选择13行。
        ------- oracle支持 隐式类型转换 ..eg char ****====>date,除此之外:
        -------- 日期转换的函数.....
        ------ 日期和字符串''
        -------日期是格式敏感

select ….
from …..
where col > 30
col in (a,b,c) –特别注意,此处的in只能从括号中已有的值进行选取,并不是表示的范围
col between a and b .. a要小b []

1 查询工资在1000~2000之间的员工信息

  select * 
  from emp
  where sal between 1000 and 2000

   select * 
  from emp
  where sal >=1000 and sal <=2000  

       EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO

  7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
  7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
  7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
  7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
  7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
  7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

1 select *
2 from emp
3* where sal between 1000 and 200
SQL> /

2 查询10 20号部门的员工信息

查询不是10 20号部门的员工信息
select * from emp
where DEPTNO in (10, 20)

    select * from emp
   where DEPTNO not in (10, 20)

             EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
        ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
              7369 SMITH      CLERK           7902 17-12月-80            800                    20
              7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
              7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
              7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
              7839 KING       PRESIDENT            17-11月-81           5000                    10
              7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
              7902 FORD       ANALYST         7566 03-12月-81           3000                    20
              7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

3 in 中是一个集合 …..null

select * from emp
where DEPTNO in (10, 20, null)

    select * from emp
   where DEPTNO not in (10, 20)     

   ======> in集合中遇见null  (in集合和空值在一起...)
   =====>in (集合中含有空值 ) 查询结果不受影响
   ======>not in (集合中含有空值 ) 查询结果受影响
   why? .

4 like模糊查询

% 代表零个或多个字符(任意个字符)。
_ 代表一个字符。
查询名字S开头的员工信息    
              1  select * from emp
          2*    where ENAME like 'S%'  
          ---''单引号中的字符串是区分大小写的....
        SQL> /

             EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
        ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
              7369 SMITH      CLERK           7902 17-12月-80            800                    20
              7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20


**查询名字含有4个字母的员工**

 select * from emp
 where ENAME like '____'

              1  select * from emp
      2*     where ENAME like '____'
    SQL> /

         EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
    ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
          7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
          7839 KING       PRESIDENT            17-11月-81           5000                    10
          7902 FORD       ANALYST         7566 03-12月-81           3000                    20

查询名字含有下划线的员工 (查询的内容含有转义字符)
先往表中插入一行(由于原表中没有名字含有下划线的员工)

insert into emp(empno, ename, sal , DEPTNO) values(1, 'tom_abc', 8000, 10) 

        select * from emp
        where ename like '%\_%' escape '\'



         EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
    ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
             1 tom_abc                                              8000                    10

**回避特殊符号的:使用转义符。例如:将[%]转为[\%]、[_]转为[\_],然后再加上[ESCAPE ‘\’] 即可。**

=================ORDER BY子句

1 order by 默认按照排序 从小到大

2 order by后面+列名 表达式 别名 序号

按照薪水,查询员工信息
select *from emp
order by sal

按照年薪,查询员工信息
select empno, ename, sal, sal*12 年薪 from emp
order by 年薪

  1  select empno, ename, sal, sal*12 年薪 from emp

2* order by 年薪
SQL> /

 EMPNO ENAME             SAL       年薪

  7369 SMITH             800       9600
  7900 JAMES             950      11400
  7876 ADAMS            1100      13200
  7521 WARD             1250      15000
  7654 MARTIN           1250      15000
  7934 MILLER           1300      15600
  7844 TURNER           1500      18000
  7499 ALLEN            1600      19200
  7782 CLARK            2450      29400
  7698 BLAKE            2850      34200
  7566 JONES            2975      35700
  7902 FORD             3000      36000
  7788 SCOTT            3000      36000
  7839 KING             5000      60000
     1 tom_abc          8000      96000



****2 order by 遇上空值****
    1 任何表达式和null运算都为空
    2 null != null  (is null )
    3 where子句中(in集合和空值在一起...)
    4 


   按照奖金,查询员工信息   

1 select empno, ename, comm from emp
2 order by 3 desc
3* nulls last
SQL> /

                 EMPNO ENAME            COMM
            ---------- ---------- ----------
                  7654 MARTIN           1400
                  7521 WARD              500
                  7499 ALLEN             300
                  7844 TURNER              0
                  7782 CLARK
                  7788 SCOTT
                  7839 KING
                  7876 ADAMS
                  7900 JAMES
                  7902 FORD
                  7698 BLAKE
                  7566 JONES
                  7934 MILLER
                     1 tom_abc
                  7369 SMITH

已选择15行。

3 order by 后面有多个列,
如果多个列中 有desc修饰,只作用于最近的那一列
按照部门排序
select * from emp
order by deptno desc, sal desc;

按照部门和工资排序
select * from emp
    order by deptno desc, sal desc

/

                 EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
        ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
              7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
              7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
              7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
              7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
              7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
              7900 JAMES      CLERK           7698 03-12月-81            950                    30
              7902 FORD       ANALYST         7566 03-12月-81           3000                    20
              7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
              7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
              7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
              7369 SMITH      CLERK           7902 17-12月-80            800                    20
                 1 tom_abc                                              8000                    10
              7839 KING       PRESIDENT            17-11月-81           5000                    10
              7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
              7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

**

单行函数

**

    select ...
    from ...
    where ....
    order by ....

这里写图片描述

这里写图片描述

这里写图片描述
多行函数

        SQL> select count(*) from emp;

          COUNT(*)
        ----------
                14

字符函数

这里写图片描述

这里写图片描述

这里写图片描述

          1  select Lower('Hello') 转小写, upper('hello') 转大写, initcap('hello woRld')  首字母大写
          2*    from dual
        SQL> /

        转小  转大  首字母大写
        ----- ----- -----------
        hello HELLO Hello World

         select  concat('hello', 'world') from dual



            SQL> select  concat (concat('hello', 'world'), 'cccc')  函数嵌套 from dual;

            函数嵌套
            --------------
            helloworldcccc


            CONCAT('HE
            ----------
            helloworld

SUBSTR(a,b) — 从a中第b位 去字符串
substr(a, b, c) 从a中第b位, c个字符….

        SQL> select substr('abcdefg1111', 2) 从第二位取子串,  substr('abcdefg1111', 2, 4) 取4个字符 from dual;

        从第二位取 取4
        ---------- ----
        bcdefg1111 bcde

–length字符数 –lengthb字节数
–一个中文字符,两个字节

                SQL> select length('中国abc') 字符数,   lengthb('中国abc') 字节数 from dual;

                    字符数     字节数
                ---------- ----------
                         5                          

                SQL> \


         SQL> select instr('abcdefg', 'efg')  求子串位置 from dual;

        求子串位置
        ----------
                 5  

SQL> select lpad('abcd', 10, '*') lpad,         rpad('abcd', 10, '*') rpad from dual;

        LPAD       RPAD
        ---------- ----------
        ******abcd abcd******        

–trim 去掉前后指定的字符,字符可以是空格,也可以不是空格 .
SQL> select trim(‘A’ from ‘ABCDEFg’) from dual;

        TRIM('
        ------
        BCDEFg

========数字函数

//2 > 0 表 保留小数点2位
// 0 保留个位
//-1 保留10位
//-1 保留百位 (要看十位 四舍五入)
1 select round(45.926, 2) AA, round(45.926, 1) BB, round(45.926, 0) CC, round(45.926) DD,
2* round(45.926, -1) EE, round(45.926, -2) FF from dual
3 /

    AA         BB         CC         DD         EE         FF

 45.93       45.9         46         46         50          0

=========日期
时间的计算…….
oracle数据库中 date包含 日期和时间
mysql 3中数据类型 date time times…..
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

        select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual ;

        SQL> select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual ;

                            TO_CHAR(SYSDATE,'YY
                            -------------------
                            2014-10-07 16:34:17

        ----昨天今天明天
        select sysdate-1 昨天, sysdate 今天, sysdate+1 明天 from dual;

        select to_char(sysdate-1, 'yyyy-mm-dd hh24:mi:ss')  昨天, sysdate 今天, sysdate+1 明天 from dual;

        ----查询员工的入职时间,按照 周 月  年 方式显示.....

        select (sysdate-hiredate)/7 周,   (sysdate-hiredate)/30 月,  (sysdate-hiredate)/365 年
        from emp;



                          1  select (sysdate-hiredate)/7 周,   (sysdate-hiredate)/30 月,  (sysdate-hiredate)/365
                          2* from emp
                        SQL> /

                                周         月         年
                        ---------- ---------- ----------
                        1763.95625 411.589791 33.8292979
                        1754.67053 409.423125 33.6512157
                        1754.38482 409.356458 33.6457363
                        1748.81339 408.056458  33.538887
                        1723.24196 402.089791  33.048476
                        1744.67053 407.089791 33.4594349
                        1739.09911 405.789791 33.3525856
                        1433.38482 334.456458 27.4895719
                        1716.09911 400.423125 32.9114897
                        1726.09911 402.756458 33.1032705
                        1428.52768 333.323125 27.3964212
                        1713.81339 399.889791 32.8676541
                        1713.81339 399.889791 32.8676541
                        1706.52768 398.189791 32.7279281


        ---查询员工的入职时间, 入职月数 ....

        select ename, (sysdate-hiredate)/30 估计月,  MONTHS_BETWEEN(sysdate, hiredate) 函数计算月
                          from emp

          1  select ename, (sysdate-hiredate)/30 估计月,  MONTHS_BETWEEN(sysdate, hiredate) 函数计算月
          2*                              from emp
                    SQL> /

                    ENAME          估计月 函数计算月
                    ---------- ---------- ----------
                    SMITH      411.589872 405.699876
                    ALLEN      409.423205 403.603102
                    WARD       409.356539 403.538586
                    JONES      408.056539 402.183747
                    MARTIN     402.089872 396.345037
                    BLAKE      407.089872 401.216005
                    CLARK      405.789872 399.957941
                    SCOTT      334.456539  329.63536
                    KING       400.423205 394.699876
                    TURNER     402.756539 396.990199
                    ADAMS      333.323205 328.506328
                    JAMES      399.889872 394.151489
                    FORD       399.889872 394.151489
                    MILLER     398.189872 392.506328

        已选择14行。

    select next_day(sysdate, '星期六') from dual 



            SQL> select next_day(sysdate, '星期六') from dual ;

            NEXT_DAY(SYSDA
            --------------
            11-10月-14

==========================数据类型转换==============
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

select *
2 from emp
3* where hiredate > ‘01-1月 -81’
日期相关类型转换
—比这个日期都要大的08-9月 -81 所有员工信息 按照三种方式实现

select * from emp
where hiredate > '01-1月 -81'  --隐式类型转换

select * from emp
where hiredate > to_date('1981-01-01 02:03:04', 'yyyy-mm-dd hh24:mi:ss') --字符串转成日期...显示类型转换



select * from emp
where to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss') > '1981-01-01 02:03:04'


          1  select * from emp
          2*    where hiredate > to_date('1981-01-01 02:03:04', 'yyyy-mm-dd hh24:mi:ss')
        SQL> /

             EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
        ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
              7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
              7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
              7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
              7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
              7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
              7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
              7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
              7839 KING       PRESIDENT            17-11月-81           5000                    10
              7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
              7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
              7900 JAMES      CLERK           7698 03-12月-81            950                    30
              7902 FORD       ANALYST         7566 03-12月-81           3000                    20

====================
数字和字符串转换

–查询员工的薪水:两位小数 本地货币代码 千位符
Y1,250.00

select empno, ename, to_char(sal, ‘L9,999.99’)
from emp;

                  1  select empno, ename, to_char(sal, 'L9,999.99')
                  2*  from emp
                SQL> /

                     EMPNO ENAME      TO_CHAR(SAL,'L9,999
                ---------- ---------- -------------------
                      7369 SMITH                 ¥800.00
                      7499 ALLEN               ¥1,600.00
                      7521 WARD                ¥1,250.00
                      7566 JONES               ¥2,975.00
                      7654 MARTIN              ¥1,250.00
                      7698 BLAKE               ¥2,850.00
                      7782 CLARK               ¥2,450.00
                      7788 SCOTT               ¥3,000.00
                      7839 KING                ¥5,000.00
                      7844 TURNER              ¥1,500.00
                      7876 ADAMS               ¥1,100.00
                      7900 JAMES                 ¥950.00
                      7902 FORD                ¥3,000.00
                      7934 MILLER              ¥1,300.00

                已选择14行。

把这个字符¥1,250.00,转成数字…..
select to_number(‘¥1,250.00’, ‘L9,999.99’) from dual ;

            SQL> select to_number('¥1,250.00', 'L9,999.99') from dual ;

            TO_NUMBER('¥1,250.00','L9,999.99')
            -----------------------------------
                                           1250

通用函数

=======条件表达式 做报表

-给员工涨工资:总裁 1000 经理:800 其他涨500,
前后工资给列出来

PRESIDENT

MANAGER

if (job == ‘PRESIDENT’)
SAL+1000
else if (job == ‘MANAGER’)
SAL+800
else
SAL+500

CASE expr WHEN comparison_expr1 THEN return_expr1
[WHEN comparison_expr2 THEN return_expr2
WHEN comparison_exprn THEN return_exprn
ELSE else_expr]
END

CASE job when ‘PRESIDENT’ then sal+1000
when ‘MANAGER’ then sal+800
else sal + 500
END

select ename, job, sal 涨前工资,
(
CASE job when ‘PRESIDENT’ then sal+1000
when ‘MANAGER’ then sal+800
else sal + 500
END
)

 涨后工资

from emp

            ENAME      JOB         涨前工资   涨后工资
            ---------- --------- ---------- ----------
            SMITH      CLERK            800       1300
            ALLEN      SALESMAN        1600       2100
            WARD       SALESMAN        1250       1750
            JONES      MANAGER         2975       3775
            MARTIN     SALESMAN        1250       1750
            BLAKE      MANAGER         2850       3650
            CLARK      MANAGER         2450       3250
            SCOTT      ANALYST         3000       3500
            KING       PRESIDENT       5000       6000
            TURNER     SALESMAN        1500       2000
            ADAMS      CLERK           1100       1600
            JAMES      CLERK            950       1450
            FORD       ANALYST         3000       3500
            MILLER     CLERK           1300       1800

            已选择14行。

第二种方法

DECODE(col|expression, search1, result1
[, search2, result2,…,]
[, default])

decode(job, ‘PRESIDENT’, sal+10000, ‘MANAGER’, sal+800, sal+500)
select ename, job, sal 涨前工资,
(
decode(job, ‘PRESIDENT’, sal+10000, ‘MANAGER’, sal+800, sal+500)
)

 涨后工资

from emp

**

多行函数-分组依据-分组过滤

**
select …..
from ….
where col in ..
col >
col between a and b
order by ….
group by ….
having……

组函数
1
1 select avg(sal), sum(sal), max(sal), min(sal), count(sal)
2* from emp
3 /

                  AVG(SAL)   SUM(SAL)   MAX(SAL)   MIN(SAL) COUNT(SAL)
                ---------- ---------- ---------- ---------- ----------
                2073.21429      29025       5000        800         14


    2--组函数和null在一起.....

        求员工的平局奖金
                select avg(comm) 方式1, sum(comm)/count(comm) 方式2, sum(comm)/count(*) 方式3
                from emp

        select count(comm), count(*) from emp ;


                SQL> select count(comm), count(*) from emp ;

                COUNT(COMM)   COUNT(*)
                ----------- ----------
                          4         14

          *-----组函数自动滤空 .... 组函数忽略空值。*
          -----修正组函数的滤空  select count(nvl(comm, 0)), count(*) from emp ;


                SQL>  select count(nvl(comm, 0)), count(*) from emp;

                COUNT(NVL(COMM,0))   COUNT(*)
                ------------------ ----------
                                14         14

**分组数据
1 求各个部门的平均工资..**

思想: 需要把各个部门的数据划分....... 10部门 20部门 30部门.....分组... 

select  deptno,  avg(sal)
from emp
group by deptno;


          1  select  deptno,  avg(sal)
          2     from emp
          3*    group by deptno
        SQL> /

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

2 组函数设计的本意

select a, b, c
from emp
group by a, b, c,d; –ok

select a, b, f
from emp
group by a, b, c,d; –err

——– 1 select检索的列 必须要位于 group by后面的集合列中
2 组函数设计的本意: 必须要在分组数据之上, 进行结果集的检索…. …
注意: group by字句要求: 所有在select中出现的列,都必须在出现在group by分组子句中.

      1  select  deptno,  avg(sal), ename
      2     from emp
      3*    group by deptno
    SQL> /
    select  deptno,  avg(sal), ename
                               *
    第 1 行出现错误:
    ORA-00979: 不是 GROUP BY 表达式

这里写图片描述
3在GROUP BY 子句中包含多个列

--按部门 不同的职位 统计平均工资
先按照部门分组,再按照job分组,如果deptno和job一样,就是同一组,然后求平均工资


--求各个部门的,每一个工种的平均工资

select ....
from emp
group by deptno, job




              1  select  deptno, job,  avg(sal), count(deptno)
              2     from emp
              3     group by deptno, job
              4*    order by 1
            SQL> /

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

            已选择9行。

这里写图片描述
分组过滤

--查询各个部门的平均工资 

1 进一步,查询平均工资大于2000的部门

    查询平均工资大于2000的部门
    select deptno, avg(sal)
    from emp
    group by deptno
    having avg(sal) > 2000

      1  select deptno, avg(sal)
      2             from emp
      3             group by deptno   ---先分组 再过滤
      4*            having avg(sal) > 2000
    SQL> /

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

这里写图片描述
2 having 和where子句区别

求10号部门的平均工资
—方法1 —先分组 再过滤
select deptno, avg(sal)
from emp
group by deptno
having deptno=10

—方法2 —先过滤在分组…..
select deptno, avg(sal)
from emp
where deptno =10
group by deptno

select deptno, avg(sal)
from emp
where deptno =10
group by deptno

======> 哪一个好….sql优化 方法2好 ….

select * from emp;
select deptno, ename, …, from emp –显示的把所有的列都写出来,速度快,,不需要”翻译”

select *form emp
where (deptno = 10) and (deptno=20) and (deptno=30)

            <---------

oracle解析逻辑表达式 的方向….从右向左

**

多表查询

**

select …
from table1, table2
where ….
order by ….
group by ….
having …

笛卡尔积基本原理
两个表如果笛卡尔积运算
1 行数 两个表相乘
2 列数 两个表相加..

          1  select count(e.EMPNO)
          2      from  emp e, dept d
          3*     where e.deptno = d.deptno
        SQL> /

        COUNT(E.EMPNO)
        --------------
                    14

        SQL> ed
        已写入 file afiedt.buf

          1  select count(e.EMPNO)
          2*     from  emp e, dept d
          3  /

        COUNT(E.EMPNO)
        --------------
                    56

等值连接
eg:查询员工信息,员工号,姓名,月薪,部门名称

select e.empno, e.ename, e.sal, d.dname
from emp e, dept d
where e.deptno = d.deptno


 EMPNO ENAME             SAL DNAME

  7369 SMITH             800 RESEARCH
  7499 ALLEN            1600 SALES
  7521 WARD             1250 SALES
  7566 JONES            2975 RESEARCH
  7654 MARTIN           1250 SALES
  7698 BLAKE            2850 SALES
  7782 CLARK            2450 ACCOUNTING
  7788 SCOTT            3000 RESEARCH
  7839 KING             5000 ACCOUNTING
  7844 TURNER           1500 SALES
  7876 ADAMS            1100 RESEARCH
  7900 JAMES             950 SALES
  7902 FORD             3000 RESEARCH
  7934 MILLER           1300 ACCOUNTING

不等值连接
eg:查询员工信息,员工号,姓名,月薪, 薪水级别
select e.empno, e.ename, e.sal, s.grade
from emp e, salgrade s
where e.sal>=s.losal and e.sal<=s.hisal

          1  select e.empno, e.ename, e.sal, s.grade
      2     from emp e, salgrade s
      3*    where e.sal>=s.losal and e.sal<=s.hisal
    SQL> /

         EMPNO ENAME             SAL      GRADE
    ---------- ---------- ---------- ----------
          7369 SMITH             800          1
          7900 JAMES             950          1
          7876 ADAMS            1100          1
          7521 WARD             1250          2
          7654 MARTIN           1250          2
          7934 MILLER           1300          2
          7844 TURNER           1500          3
          7499 ALLEN            1600          3
          7782 CLARK            2450          4
          7698 BLAKE            2850          4
          7566 JONES            2975          4
          7788 SCOTT            3000          4
          7902 FORD             3000          4
          7839 KING             5000          5

外连接

eg:按部门统计员工人数: 部门号 部门名称 各部门人数
---思路1:  求各个部门的人数...要把各个部门数据划分开.....要分组.....
        2:各部门人数 员工表 
        =====>因为 部门人数 是由员工表确定的...所以还要检索员工表...
        所以需要多表查询


        select d.deptno, d.dname, count(e.empno)
        from dept d, emp e
        where d.deptno = e.deptno (+)
        group by d.deptno,  d.dname



        DEPTNO DNAME          COUNT(E.EMPNO)
    ---------- -------------- --------------
            10 ACCOUNTING                  3
            20 RESEARCH                    5
            30 SALES                       6


---我们的期望 想把40号部门给统计出来...
----40号部门没有被统计出来的原因: 员工表中没有40号部门的员工...d.deptno = e.deptno (d.40 = e.40)
------本质:等值条件不满足...
========>外连接技术出现的原因
+左外连接:  +号在..=号的右边,左外连接....
+右外连接:  +号在..=号的左边,左外连接....
        我想把部门表的所有列都显示出来, 就需要找到部门表..在对方写(+)



      1  select d.deptno, d.dname, count(e.empno)
      2                     from dept d, emp e
      3                     where d.deptno = e.deptno(+)
      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

自连接
– 查询员工信息 ,老板信息
显示: *的老板是*

---思路1: 员工信息 查员工表
        查老板信息,还要查员工表...

---思路2 员工表的老板 是  老板表的员工     
        select e.ename, b.ename
        from emp e, emp b
        where e.mgr = b.empno


        select e.ename || '的老板是' || b.ename
        from emp e, emp b
        where e.mgr = b.empno (+)


        E.ENAME||'的老板是'||B.ENAME
        ----------------------------
        SMITH的老板是FORD
        ALLEN的老板是BLAKE
        WARD的老板是BLAKE
        JONES的老板是KING
        MARTIN的老板是BLAKE
        BLAKE的老板是KING
        CLARK的老板是KING
        SCOTT的老板是JONES
        KING的老板是
        TURNER的老板是BLAKE
        ADAMS的老板是SCOTT
        JAMES的老板是BLAKE
        FORD的老板是JONES
        MILLER的老板是CLARK

        已选择14行。


            select e.ename || '的老板是' || nvl (b.ename, '他自己')
        from emp e, emp b
        where e.mgr = b.empno (+)

        E.ENAME||'的老板是'||NVL(B.E
        ----------------------------
        SMITH的老板是FORD
        ALLEN的老板是BLAKE
        WARD的老板是BLAKE
        JONES的老板是KING
        MARTIN的老板是BLAKE
        BLAKE的老板是KING
        CLARK的老板是KING
        SCOTT的老板是JONES
        KING的老板是他自己
        TURNER的老板是BLAKE
        ADAMS的老板是SCOTT
        JAMES的老板是BLAKE
        FORD的老板是JONES
        MILLER的老板是CLARK

        已选择14行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值