zoukankan      html  css  js  c++  java
  • Oracle-- 查询、聚合函数、多表连接、子查询

    语法:

    select  *(所有列)/列名1.列名2.,,,  from  表名
       [where  条件]  --对整张表的筛选
       [group by  列名1[,列名2,...]]    分组
       [having 条件]     --对分组之后的筛选
       [order by  列名  排序方式[,列名2  排序方式2,...]  --排序

    null查询:与任何运算符进行计算的时候都是null

      (与null判断, 不能使用 = !=  一定使用 is null 或者 is not null)

    nvl(列名, 转换的值) 如果列中值是null, 返回转换的值, 如果列中的值不是null, 返回列的值

    select ename, sal + nvl(comm,0)  from emp;

    多列合并  使用 || 连接符

    select ename||'$'|| (sal + nvl(comm,0)) "月收入" from emp  e;

    去重 关键字  distinct

      所有列的最前面

    select distinct  job from emp;

    in(值的集合) 

    -- 表示列中的值是集合任何一个都满足
    select  *  from EMP where  empno in (7369,7788,7902);

    between 小值 and  大值:

    -- 大于等于小值, 小于等于大值
    select  *  from EMP where sal  between  800 and 3000;

    模糊查询

      列名 like '表达式'
       _一个任意的字符 %: 任意多个任意字符

    --查询姓名以S开头的
    select *  from emp where ename like 'S%';
    -- 查询姓名由五个字符组成
    select *  from emp where ename like '_____';

    聚合函数

    • COUNT():统计指定列不为NULL的记录行数;
    • MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算; a-z
    • MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
    • SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
    • AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;

    分组  group by 列

      使用group by 进行分组,  select 后面只能接 分组中出现的列, 聚合函数

    having

      对分组的数据进行筛选

    注意: where 与having的区别: 筛选
    -- 1) 位置不同, where在group by之前, having 是在group by之后
    -- **** 2) where 的条件不能使用聚合函数, 使用表所有的列名 having 可以使用聚合函数, 只能使用group by 出现的列
    -- 3) where 对整张表进行筛选, having 对分组之后的数据来筛选

    多表查询

    表连接分类: 内连接,  左外连接, 右外连接

    内连接:

      A内连接 B 要求A的一条记录一定在B中有一条数据与它对象, B的一条记录需要A有一条记录对应,这样才显示
      没有对应的数据, 排除

    写法: 非标准写法:

    select * from emp e,dept d  where e.deptno = d.deptno;

    标准写法:

    -- select  */列名  from 表1 [inner] join 表2   on 连接的条件
    select *  from emp e inner join dept d  on  e.deptno = d.deptno;

    表连接: 可以n张表进行连接, 连接的条件 不一定是等值连接

    select * from emp e join dept d
    on e.deptno = d.deptno
    join salgrade s
    on e.sal BETWEEN s.losal and s.HISAL;

    外连接

        左外: join左边的表为主, 把左边的表的数据全部查询出来,
        右外: join右边的表为主, 把右边的表的数据全部查询出来,

    左外连接

      左边表的数据全部显示

      先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示NULL

    标准写法:  left [outer]  join   
    --  左表: emp     右表: dept
      select *  from emp e  left outer join dept d 
      on  e.deptno = d.deptno;

    右外连接

      先查询出右表(即以右表为主),然后查询左表,左表中满足条件的显示出来,不满足条件的显示NULL

    结果一样
    --标准写法:  right [outer] join 
    select *  from emp e  right  join dept d 
    on  e.deptno = d.deptno;
    --左外
    select *  from dept d  left  join emp e 
    on  e.deptno = d.deptno;

    子查询

      一个select语句中包含其他的select语句, 这个查询叫: 子查询

    子查询出现的位置:
      where后,作为条件的一部分;
      from后,作为被查询的一条表;
      select后, 作为被查询的一列(很少用)
    当子查询出现在where后作为条件时,还可以使用如下关键字: 结合 > < >= =<
      any 任意一个 >any
      all 所以 >all

    比较运算符: > < = != ....  要求后面的结果是一个值
    -- all(子查询)  所有     >all  --> 大于所有(大于最大值)     <all --> 小于所有(小于最小值)
    -- any(子查询)  任意一个  >any --> 大于任意一个(大于最小值)   <any-->小于任意一个(小于最大值)

    子查询结果集的形式
      单行单列(用于条件)
      单行多列(用于条件)
      多行单列(用于条件)
      多行多列(用于表)

    单行单列:

    select * from emp where sal > (
      select sal from emp where ename='ALLEN'
    );

    单行多列:

    select sal from emp where deptno = 30;

    多行单列:

    select * from emp where sal > all
    (
       select sal from emp where deptno = 30
    );
     select sal from emp where deptno = 30;
    --第二种写法: 大于最大值
    select * from emp where sal >
    (
       select max(sal) from emp where deptno = 30    --查询出30部门最大值
    );

    多行多列:

    --查询员工编号为7369的员工名称、员工工资(emp)、部门名称、部门地址(dept)
      --第一种写法: 表连接
      select e.ename,e.sal,d.dname,d.LOC   from  emp e, dept d 
      where e.deptno = d.deptno
      and e.empno = 7369;
     
     --第二种写法: 使用子查询
     -- 注意, 如果子查询作为表来使用,  这个子查询的一定要起别名, 
     --  不是给子查询起别名, 这个别名是给子查询查询出来的虚拟表起的别名
     --  子查询中查询的列取别名, 子查询作为表来用, 虚拟表, 列使用列别名
     select e.ename,e.sal,t.dname,t.LOC   from emp e ,(select deptno dno,dname,loc from dept) t
     where  e.deptno = t.dno
     and  e.empno=7369;

    使用in的子查询

    -- in 前面的小括号的列顺序要与 子查询的select 后的列顺序一致
    select * from emp where (job,sal) in (select job,sal from emp where ename='MARTIN')
    and ename !='MARTIN';

    【  相关子查询  】:

        子查询的执行必须依赖于主查询, 这个子查询不能独立运行, 先主查询,再把主查询的数据传递子查询

    【  非相关子查询  】:

         前面写的所有的子查询都是非相关子查询:

     --非相关子查询
     -- in, exists 这两种写法, 有一个效率差异( 内层数据量, 外层数据量)
     --  外层数据量大,  in 效率高
     --  内层数据量大,  exists效率高
     select * from dept where deptno in( select deptno from emp where sal > 3000);
     
     
     --相关子查询:  exists(子查询)
     --exists的相关子查询只关心内层查询是否有返回值;当内层没有返回值时,外层也没有结果.如果内层有返回值,将内层的结果去查询外层数据
     select *  from dept d
     where exists(
        select 1 from emp e where e.deptno = d.deptno and e.sal > 3000 
     );
  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/64Byte/p/12694634.html
Copyright © 2011-2022 走看看