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 
 );
原文地址:https://www.cnblogs.com/64Byte/p/12694634.html