Oracle数据库学习二

5.多表查询

多表查询

目的:从多张表获取数据

前提:进行连接的多张表中有共同的列

等连接

通过两个表具有相同意义的列,建立连接条件.

查询结果只显示两个列中的值是等值条件的行数据

表中同名列被选择时必须添加表名前缀进行修饰 否则无法确定这一列是属于哪个表

不等连接

A表中的某列数据和B表中一列或多列的关系是非等值关系,大于,小于,不等于,等条件都属于不等连接的范畴

自连接

数据都来自一张表,所以在from字句中需要对表添加别名,添加表别名后才能合法化的引用表中的列名.

本质就是将一张表虚拟成了两张表

外连接

即是选择出满足等连接条件及其以外的行

(+)修饰符号用法:放置在选出结果只包含等连接的列后,则另一列的结果就是等值行+非等值行

全连接

全链接是把做符合和不符合关联条件的两个表的信息都显示出来

等链接

SQL> select *from emp,dept where emp.deptno=dept.deptno;

EMPNO ENAME      JOB   MGR HIREDATE       SAL COMM   DEPTNO    DEPTNO DNAME   LOC

---------- ---------- --------- ----- --------- ---------- ---------- ---------- ---------- -------------- ----------

7782 CLARK      MANAGER 7839 09-JUN-81      2450       10 10 ACCOUNTING   NEW YORK

7839 KING      PRESIDENT      17-NOV-81      5000       10 10 ACCOUNTING   NEW YORK

7934 MILLER    CLERK 7782 23-JAN-82      1300       10 10 ACCOUNTING   NEW YORK

7566 JONES      MANAGER 7839 02-APR-81      2975       20 20 RESEARCH   DALLAS

7902 FORD      ANALYST 7566 03-DEC-81      3000       20 20 RESEARCH   DALLAS

7876 ADAMS      CLERK 7788 23-MAY-87      1100       20 20 RESEARCH   DALLAS

7369 SMITH      CLERK 7902 17-DEC-80        800       20 20 RESEARCH   DALLAS

7788 SCOTT      ANALYST 7566 19-APR-87      3000       20 20 RESEARCH   DALLAS

7521 WARD      SALESMAN 7698 22-FEB-81      1250   500       30 30 SALES   CHICAGO

7844 TURNER    SALESMAN 7698 08-SEP-81      1500     0       30 30 SALES   CHICAGO

7499 ALLEN      SALESMAN 7698 20-FEB-81      1600   300       30 30 SALES   CHICAGO

7900 JAMES      CLERK 7698 03-DEC-81        950       30 30 SALES   CHICAGO

7698 BLAKE      MANAGER 7839 01-MAY-81      2850       30 30 SALES   CHICAGO

7654 MARTIN    SALESMAN 7698 28-SEP-81      1250 1400       30 30 SALES   CHICAGO

标准sql写法:

SQL> select empno,ename,loc from emp inner join dept on emp.deptno=dept.deptno;

idle>

这才是我们要的结果.笛卡尔积几乎我们不会需要.多表查询时基本都带有where子句来描述多个表的关系 避免笛卡尔集

当两个表中有相同的列名时,为了区分 要在列前加上表名作前缀.

在联合的两个表内取数据:描述scott在哪个部门

idle> select empno,ename,dname,sal from emp,dept where emp.deptno=dept.deptno and ename='SCOTT';

EMPNO ENAME      DNAME     SAL

---------- ---------- -------------- ----------

7788 SCOTT      RESEARCH   3000

为了书写方便,我们可以给表起别名

表的别名

格式:表名 别名

给表取别名是很有必要的,因为有的表名很长 不便于引用时书写.

SQL> select *from emp a,dept b where a.deptno=b.deptno and a.ename='SCOTT';

EMPNO ENAME      JOB   MGR HIREDATE       SAL COMM   DEPTNO    DEPTNO DNAME   LOC

---------- ---------- --------- ----- --------- ---------- ---------- ---------- ---------- -------------- ----------

7788 SCOTT      ANALYST 7566 19-APR-87      3000       20 20 RESEARCH   DALLAS

不等连接

就是排除完全相等条件以外的 >,<,!=, <=, >=, between and

主要在于不同表之间显示特定范围的信息(也可以理解成包含关系)

求出每个员工的工资等级

SQL> SELECT *FROM SALGRADE;

GRADE LOSAL   HISAL

---------- ---------- ----------

1   700     1200

2 1201     1400

3 1401     2000

4 2001     3000

5 3001     9999

SQL> select empno,ename,sal,grade from emp a,salgrade b where a.sal between b.losal and b.hisal;

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

14 rows selected.

自连接

同一张表内的连接查询 即把一个表映射成两个表

主要用于表的自参照关系 比如emp中的上下级或层次关系

因为自连接是同一张表之间的链接查询 所以必须定义表别名

SQL> select a.empno,a.ename,b.empno,b.ename from emp a,emp b where a.mgr=b.empno;

EMPNO ENAME   EMPNO ENAME

---------- ---------- ---------- ----------

7902 FORD     7566 JONES

7788 SCOTT     7566 JONES

7844 TURNER     7698 BLAKE

7499 ALLEN     7698 BLAKE

7521 WARD     7698 BLAKE

7900 JAMES     7698 BLAKE

7654 MARTIN     7698 BLAKE

7934 MILLER     7782 CLARK

7876 ADAMS     7788 SCOTT

7698 BLAKE     7839 KING

7566 JONES     7839 KING

7782 CLARK     7839 KING

7369 SMITH     7902 FORD

13 rows selected.

外链接

不仅返回满足连接的记录 还会返回不满足连接的记录

外链接的运算符(+)

该符号可以放在等的左边或右边,但一定要放在缺少信息(完全满足条件的行)的一边.

若加在多信息的一边 和没加一样,可以理解为谁需要空行来填补,就在谁的后面加(+)

例如:emp中不包含40号部门的员工 而dept中有40号部门

SQL> select empno,ename,b.deptno,dname from emp a,dept b where a.deptno(+)=b.deptno;

EMPNO ENAME   DEPTNO DNAME

---------- ---------- ---------- --------------

7782 CLARK       10 ACCOUNTING

7839 KING       10 ACCOUNTING

7934 MILLER       10 ACCOUNTING

7566 JONES       20 RESEARCH

7902 FORD       20 RESEARCH

7876 ADAMS       20 RESEARCH

7369 SMITH       20 RESEARCH

7788 SCOTT       20 RESEARCH

7521 WARD       30 SALES

7844 TURNER       30 SALES

7499 ALLEN       30 SALES

7900 JAMES       30 SALES

7698 BLAKE       30 SALES

7654 MARTIN       30 SALES

40 OPERATIONS

15 rows selected.

标准sql写法 left join on

查询出所有部门名和10号部门内的员工

因为员工信息显示较少 所以(+)符号放在emp.deptno上

SQL> select b.deptno,b.dname,a.empno,a.ename from emp a,dept b where a.deptno(+)=b.deptno and a.deptno(+)=10;

DEPTNO DNAME       EMPNO ENAME

---------- -------------- ---------- ----------

10 ACCOUNTING 7782 CLARK

10 ACCOUNTING 7934 MILLER

10 ACCOUNTING 7839 KING

20 RESEARCH

30 SALES

40 OPERATIONS

6 rows selected.

SQL>

SQL> 如果不在所有的条件上面写(+)就会产生这样的结果

SQL> select b.deptno,b.dname,a.empno,a.ename from emp a,dept b where a.deptno(+)=b.deptno and a.deptno=10;

DEPTNO DNAME       EMPNO ENAME

---------- -------------- ---------- ----------

10 ACCOUNTING 7782 CLARK

10 ACCOUNTING 7839 KING

10 ACCOUNTING 7934 MILLER

外连接的注意事项

1.where中有多个条件时 必须每个条件都需要使用(+)符号

2.(+)只使用于列 不能是表达式

3.(+)不能与in or一起操作

实际测试中,in是可以的,给or加上括号,提高运算优先级,也是可以的。

全连接

符合连接条件的,就连接成一行,不符合的,也全部显示出来

full join on

SQL> select a.deptno,a.dname,b.empno,b.ename from dept a full join emp b on a.deptno=b.deptno and a.deptno=10;

DEPTNO DNAME       EMPNO ENAME

---------- -------------- ---------- ----------

7369 SMITH

7499 ALLEN

7521 WARD

7566 JONES

7654 MARTIN

7698 BLAKE

10 ACCOUNTING 7782 CLARK

7788 SCOTT

10 ACCOUNTING 7839 KING

7844 TURNER

7876 ADAMS

7900 JAMES

7902 FORD

10 ACCOUNTING 7934 MILLER

30 SALES

40 OPERATIONS

20 RESEARCH

17 rows selected.

1.标准的sql写法

natual join

两个表要有共有列,并且数据类型一致

如果两个表的共有列不只一个 natural join会按所有共有列连接

SQL> select empno,ename,deptno from emp e natural join dept d;

join using 是 inner join using的缩写

USING 子句

注意事项:

1.natural join 和 using子句互斥 不能同时使用

2.所引用的列不能使用表名前缀

3.被引用的列一定是两个表的共有列

4.多列相同时只能选择一列

SQL> select empno,ename,deptno from emp e join dept d using (deptno);

join on 是inner join on的简写形式

SQL> select empno,ename,dname,loc from emp e join dept d on e.deptno=d.deptno;

left join on 是left outer join on的简写形式

左外连接

满足连接条件的数据,以及不满足连接条件的左边表的其他数据

SQL> select d.deptno,d.dname,d.loc,e.empno,ename from dept d left join emp e on d.deptno=e.deptno and d.deptno=10;

DEPTNO DNAME   LOC     EMPNO ENAME

---------- -------------- ------------- ---------- ----------

10 ACCOUNTING   NEW YORK       7782 CLARK

10 ACCOUNTING   NEW YORK       7839 KING

10 ACCOUNTING   NEW YORK       7934 MILLER

40 OPERATIONS   BOSTON

30 SALES   CHICAGO

20 RESEARCH   DALLAS

right join on 是right outer join的简写形式

右外链接

满足连接条件的数据,以及不满足连接条件的右边表的其他数据

full join on 是full outer join on的简写形式

全外连接

满足连接条件的数据,以及不满足连接条件的两边的表的其他数据

连接条件和过滤条件的区别

连接条件出现在on子句中的条件,用于限制能够进行表连接的记录

被连接的表只展示符合连接条件的数据

例如:这里的emp表是被连接的表

SQL> select d.deptno,d.dname,d.loc,e.empno,ename from dept d left join emp e on d.deptno=e.deptno and d.deptno=10;

DEPTNO DNAME   LOC     EMPNO ENAME

---------- -------------- ------------- ---------- ----------

10 ACCOUNTING   NEW YORK       7782 CLARK

10 ACCOUNTING   NEW YORK       7839 KING

10 ACCOUNTING   NEW YORK       7934 MILLER

40 OPERATIONS   BOSTON

30 SALES   CHICAGO

20 RESEARCH   DALLAS

6 rows selected.

过滤条件是用在where子句中的,用于对连接后的结果进行过滤

2.集合操作

集合操作

用于多条select语句合并结果

union 并集 去重

union all 并集 不去重

intersect 交集

minus 差集

union

A集合和B集合的合并,但去掉两集合重复的部分 会排序

输出列名按照第一条sql的输出方式展示,

所有对应的列必须具有相同的数据类型,否则报错

集合的字段名使用第一个结果集的字段名称

SCOTT@ora11g> select deptno,ename from emp where deptno in (20,30)

2          union

3          select deptno,ename from emp where deptno in (20,10)

4  ;

DEPTNO ENAME

---------- ----------

10 CLARK

10 KING

10 MILLER

20 ADAMS

20 FORD

20 JONES

20 SCOTT

20 SMITH

30 ALLEN

30 BLAKE

30 JAMES

30 MARTIN

30 TURNER

30 WARD

14 rows selected.

SCOTT@ora11g>

union all

A集合和B集合的合并,不去重,不排序

SCOTT@ora10g> select deptno,ename from emp where deptno in (20,30)

2       union all

3       select deptno,ename from emp where deptno in (20,10)

4*

SCOTT@ora10g> /

DEPTNO ENAME

---------- ----------

20 SMITH

30 ALLEN

30 WARD

20 JONES

30 MARTIN

30 BLAKE

20 SCOTT

30 TURNER

20 ADAMS

30 JAMES

20 FORD

20 SMITH

20 JONES

10 CLARK

20 SCOTT

10 KING

20 ADAMS

20 FORD

10 MILLER

19 rows selected.

SCOTT@ora11g>

intersect

两个集合的交集部分,排序并去重

SCOTT@ora11g> select deptno,ename from emp where deptno in (20,30)

2       intersect

3       select deptno,ename from emp where deptno in (20,10)

4*

SCOTT@ora10g> /

DEPTNO ENAME

---------- ----------

20 ADAMS

20 FORD

20 JONES

20 SCOTT

20 SMITH

SCOTT@ora11g>

minus

取两个集合的差集,A集合中存在,B集合中不存在的数据(取A集合中B集合不存在的数据) 去重

SCOTT@ora10g>  select deptno,ename from emp where deptno in (20,30)

2       minus

3       select deptno,ename from emp where deptno in (20,10)

4*

SCOTT@ora10g>

DEPTNO ENAME

---------- ----------

30 ALLEN

30 BLAKE

30 JAMES

30 MARTIN

30 TURNER

30 WARD

6 rows selected.

3.子查询

子查询

子查询指嵌入在其他SQL中的select语句,也称嵌套查询.

按照子查询返回结果,可将子查询分为:

单行单列  col = (sub_q)

单行多列  (col1,col2..)=(sub_q)

多行单列  col in (sub_q)

多行多列  (col1,col2...) in (sub_q)

数值 一对一  = > <

数据 一对多  > any  > all

按照子查询where条件来分

标量子查询

关联子查询

特点:

1.优先执行子查询,主查询再使用子查询的结果

2.子查询返回的列数和类型要匹配

3.子查询要用括号括起来

4.子查询返回多行要用多行关系运算符

单列单行子查询

子查询返回一行记录

查询和scott在同一部门的员工

SCOTT@ora11g> select deptno,ename,sal from emp where deptno=(select deptno from emp where ename='SCOTT');

DEPTNO ENAME     SAL

---------- ---------- ----------

20 SMITH     800

20 JONES     2975

20 SCOTT     3000

20 ADAMS     1100

20 FORD     3000

SCOTT@ora11g>

也可以把子查询结果当成一列

SCOTT@ora10g> select deptno,ename,(select deptno from emp where ename='SCOTT') AA from emp where deptno=10;

DEPTNO ENAME       AA

---------- ---------- ----------

10 CLARK       20

10 KING       20

10 MILLER       20

多行子查询

多行子查询指返回多行数据的子查询语句

当在where中使用时,必须使用多行比较符(in all any)

ALL和any操作符不能独立使用 要与单行比较符(= > < >= <= <>)结合使用

in  匹配于子查询结果的任一个值即可

ALL  必须要符合子查询结果的所有值

ANY  只要符合子查询结果的任意一个值即可

in 操作

SCOTT@ora10g> select empno from emp where deptno=10;

EMPNO

----------

7782

7839

7934

SCOTT@ora10g> select empno,ename,sal from emp where empno in (select empno from emp where deptno=10);

EMPNO ENAME     SAL

---------- ---------- ----------

7782 CLARK     2450

7839 KING     5000

7934 MILLER     1300

any 操作

小于最大的即可

SCOTT@ora10g> select deptno,ename,sal from emp where deptno < any (select distinct deptno from emp where deptno = 20 or deptno = 30);

DEPTNO ENAME     SAL

---------- ---------- ----------

10 CLARK     2450

10 KING     5000

10 MILLER     1300

20 JONES     2975

20 FORD     3000

20 ADAMS     1100

20 SMITH     800

20 SCOTT     3000

8 rows selected.

SCOTT@ora10g>

ALL 操作

小于最小的即可

SCOTT@ora10g> select deptno,ename,sal from emp where deptno < all (select distinct deptno from emp where deptno = 20 or deptno = 30);

DEPTNO ENAME     SAL

---------- ---------- ----------

10 CLARK     2450

10 KING     5000

10 MILLER     1300

多列子查询

指子查询返回多个列的数据

当多个列只有一行数据时 可以使用单行比较符

当多个列有多行数据时,还是需要 IN

多列单行

就是多条件比较

查询和SMITH相同部门 相同岗位的人

SCOTT@ora11g> select deptno,ename,job,sal from emp where (deptno,job) = (select deptno,job from emp where ename='SMITH');

DEPTNO ENAME      JOB       SAL

---------- ---------- --------- ----------

20 SMITH      CLERK       800

20 ADAMS      CLERK       1100

SCOTT@ora10g>

多列多行

IN

找出领导和工资与SCOTT和WARD一致的人

SCOTT@ora11g> select ename,mgr,sal from emp where ename in ('SCOTT','WARD');

ENAME   MGR     SAL

---------- ---------- ----------

WARD 7698     1250

SCOTT 7566     3000

SCOTT@ora11g> select deptno,ename,mgr,sal from emp where (mgr,sal) in (select mgr,sal from emp where ename in ('SCOTT','WARD')) and ename not in ('SCOTT','WARD');

DEPTNO ENAME     MGR SAL

---------- ---------- ---------- ----------

30 MARTIN     7698      1250

20 FORD     7566      3000

查找每个部门的最高工资的员工姓名

SCOTT@ora10g> select deptno,max(sal) from emp group by deptno;

DEPTNO  MAX(SAL)

---------- ----------

30 2850

20 3000

10 5000

SCOTT@ora10g> select deptno,ename,sal from emp where (deptno,sal) in (select deptno,max(sal) from emp group by deptno);

DEPTNO ENAME     SAL

---------- ---------- ----------

30 BLAKE     2850

20 SCOTT     3000

10 KING     5000

20 FORD     3000

关联子查询

将主查询的内容传递给子查询 子查询再把查询结构反馈给主查询

子查询执行的次数取决于主查询传递值的次数

找出每个部门工资最高的人

不使用关联子查询 使用in分组方式实现

查找每个部门的最高工资的员工姓名

SCOTT@ora10g> select deptno,max(sal) from emp group by deptno;

DEPTNO  MAX(SAL)

---------- ----------

30 2850

20 3000

10 5000

SCOTT@ora10g> select deptno,ename,sal from emp where (deptno,sal) in (select deptno,max(sal) from emp group by deptno);

DEPTNO ENAME     SAL

---------- ---------- ----------

30 BLAKE     2850

20 SCOTT     3000

10 KING     5000

20 FORD     3000

一一比较模式

SQL> select deptno,ename,sal from emp where sal = (select max(sal) from emp where deptno=10) and deptno=10;

DEPTNO ENAME     SAL

---------- ---------- ----------

10 KING     5000

SQL> select deptno,ename,sal from emp where sal = (select max(sal) from emp where deptno=20) and deptno=20;

DEPTNO ENAME     SAL

---------- ---------- ----------

20 SCOTT     3000

20 FORD     3000

SQL> select deptno,ename,sal from emp where sal = (select max(sal) from emp where deptno=30) and deptno=30;

DEPTNO ENAME     SAL

---------- ---------- ----------

30 BLAKE     2850

SQL>

使用关联子查询模式

SQL> select deptno,ename,sal from emp e where sal = (select max(sal) from emp where deptno=e.deptno);

DEPTNO ENAME     SAL

---------- ---------- ----------

30 BLAKE     2850

20 SCOTT     3000

10 KING     5000

20 FORD     3000

SQL>

关联子查询出现在select字段中

SQL> select empno,ename,deptno,(select loc from dept where deptno=e.deptno) loc from emp e;

EMPNO ENAME          DEPTNO LOC

---------- ---------- ---------- -------------

7369 SMITH              20 DALLAS

7499 ALLEN              30 CHICAGO

7521 WARD              30 CHICAGO

7566 JONES              20 DALLAS

7654 MARTIN            30 CHICAGO

7698 BLAKE              30 CHICAGO

7782 CLARK              10 NEW YORK

7788 SCOTT              20 DALLAS

7839 KING              10 NEW YORK

7844 TURNER            30 CHICAGO

7876 ADAMS              20 DALLAS

7900 JAMES              30 CHICAGO

7902 FORD              20 DALLAS

7934 MILLER            10 NEW YORK

已选择14行。

exists查询

使用EXISTS语句可以测试集合是否为空,

EXISTS语句通常与子查询结合在一起使用。

只要子查询中至少返回一个值,则EXISTS语句的值就为True。\

查到就不再继续查

找出领导 此员工的empno在mgr列存在即是领导

SCOTT@ora10g> select empno,ename,mgr from emp e where exists (select 1 from emp where mgr=e.empno);

EMPNO ENAME     MGR

---------- ---------- ----------

7902 FORD     7566

7698 BLAKE     7839

7839 KING

7566 JONES     7839

7788 SCOTT     7566

7782 CLARK     7839

6 rows selected.

in也能做到 只是in的效率不高 in会一直比下去 而exists比成功就不在比了.

SCOTT@ora10g> select empno,ename,mgr from emp where empno in (select mgr from emp);

EMPNO ENAME     MGR

---------- ---------- ----------

7902 FORD     7566

7698 BLAKE     7839

7839 KING

7566 JONES     7839

7788 SCOTT     7566

7782 CLARK     7839

6 rows selected.

SCOTT@ora10g>

取反

用in改写时并不一定得到和not exists一致的结果

即是查找普通员工 不是领导的人

SQL> select empno,ename from emp e where not exists (select 1 from emp where mgr=e.empno);

EMPNO ENAME

---------- ----------

7844 TURNER

7521 WARD

7654 MARTIN

7499 ALLEN

7934 MILLER

7369 SMITH

7876 ADAMS

7900 JAMES

8 rows selected.

SQL>

SQL> select empno,ename from emp e where empno in (select mgr from emp);

EMPNO ENAME

---------- ----------

7902 FORD

7698 BLAKE

7839 KING

7566 JONES

7788 SCOTT

7782 CLARK

6 rows selected.

SQL> select empno,ename from emp e where empno not in (select mgr from emp);

no rows selected

SQL> 原因是什么?

with 语句

当查询中多次用到某一部分时,可以用with语句创建一个公共临时表。

因为子查询在内存临时表中,避免了重复解析,所以执行效率会提高不少。

临时表在一次查询结束自动清除。

语法: 一个select里的一个子查询  有效范围在这个SQL执行周期内

第一次执行(解析 执行 得到结果)

第二次执行(解析 执行 得到结果)

第一次执行(解析 执行 得到结果) ==> 缓存到临时表

第二次执行 (直接取结果)

with

alias_name1 as    (subquery1),

alias_name2 as    (subQuery2),

……,

alias_nameN as    (subQueryN)

select col1,col2…… col3

from alias_name1,alias_name2……,alias_nameN

例子:

SQL> with

q1 as (select 3+5 s from dual),

q2 as (select 3*5 m from dual),

q3 as (select s,m,s+m,s*m from q1,q2)

select * from q3;

S     M     S+M S*M

---------- ---------- ---------- ----------

8   15       23 120

SQL>

查询每个部门大于平均工资的员工,也可以这样来实现

SQL> with

2  a as (select deptno,avg(sal) x from emp group by deptno)

3  select * from emp,a where emp.deptno=a.deptno and emp.sal>a.x;

EMPNO ENAME      JOB       MGR HIREDATE     SAL      COMM    DEPTNO   DEPTNO   X

---------- ---------- --------- ---------- --------- ---------- ---------- ---------- ---------- ----------

7499 ALLEN      SALESMAN       7698 20-FEB-81   1600        300   30       30 1566.66667

7566 JONES      MANAGER       7839 02-APR-81   2975   20       20      2175

7698 BLAKE      MANAGER       7839 01-MAY-81   2850   30       30 1566.66667

7788 SCOTT      ANALYST       7566 19-APR-87   3000   20       20      2175

7839 KING      PRESIDENT   17-NOV-81   5000   10       10 2916.66667

7902 FORD      ANALYST       7566 03-DEC-81   3000   20       20      2175

with子句中的视图叫做询问块,询问块的复杂查询在

with子句中只运行一次,运行成功后会将询问块的结果集

保存到temp表空间,以后再次调用询问块时会在后台转换

为对结果集的直接访问

4.DDL

DDL 语句 数据定义语言

CREATE 创建

ALTER 修改

DROP 删除

TRUNCATE 截断

COMMNET 注释

RENAME 更名


修改表名

rename old_name to new_name

SQL> rename t5 to t6;

表已重命名。

增加列

alter table table_name add(column datatype [default expr] [,column datatype...])

SQL> alter table t6 add(id number default 1000);

修改列的定义

(修改后的数据类型不能与列中当前的数据冲突,

否则列必须为空,default值的修改只对后续insert数据有效,之前的数据不受影响)

alter table table_name modify(column datatype [default expr] [,column datatype...)

删除列,不管有无数据均可以删除,但是最后一列是不可以被删除的。

alter table drop (column)

SQL> alter table t2 drop (id);

表已更改。

使用SET UNUSED 选项标记一列或多列为unused

使用DROP UNUSED COLUMNS 选项删除unused列。

这个功能可以在系统高峰期因删除字段而带来影响,因为删除字段会记录undo,因此可以先把列标记为unused等系统不繁忙的时候再drop掉。

语法:

ALTER TABLE  <table_name>SET  UNUSED()(<column_name>);

ALTER TABLE  <table_name>SET  UNUSED COLUMN(<column_name>);

ALTER TABLE  <table_name>DROP  UNUSED COLUMNS;

修改列名(列名称不可以与关键字冲突,不如类型名称,命令名称等)

alter table table_name rename column old_column_name to new_column_name

SQL> alter table t2 rename column sal to salary;

表已更改。

增加注释

comment on table table_name is 'text'

comment on column table_name.columb is 'text'

user_tab_comments  表的注释信息,在这里面可以查到

user_col_comments  列的注释信息,在这里可以查到

截断表

保留表结构

清空表的数据

tuncate table table_name

属于ddl语句,同样都有删除数据的功能,但是有以下不同

truncate 可以回收存储空间,delete不会

delete可以回退,truncate不可以

工作中,慎重使用truncate

删除表

drop table table_name [purge]

10G中增加了回收站功能,表没有被完全删 只是放到回收站里去了

SQL> drop table t2;

表已删除。

从回收站中恢复表

SQL> show recyclebin;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T4 BIN$M1uFYjFloJrgUAB/AQALVQ==$0 TABLE     2016-05-21:21:52:41

或者

select *from recyclebin;

SQL> flashback table t4 to before drop;

Flashback complete.

例如:

SQL> flashback table t4 to before drop;

Flashback complete.

SQL> select *from tab;

TNAME       TABTYPE CLUSTERID

------------------------------ ------- ----------

BONUS       TABLE

DEPT       TABLE

EMP       TABLE

SALGRADE       TABLE

T4       TABLE

SQL> drop table t4;

Table dropped.

SQL>

SQL>

SQL> show recycle

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T4 BIN$M1uFYjFmoJrgUAB/AQALVQ==$0 TABLE     2016-05-21:21:57:42

还原已删除的表并改名

SQL> flashback table t4 to before drop rename to t7;

Flashback complete.

SQL> select *from tab;

TNAME       TABTYPE CLUSTERID

------------------------------ ------- ----------

BONUS       TABLE

DEPT       TABLE

EMP       TABLE

SALGRADE       TABLE

T7       TABLE

如果回收站里的表名有重复,默认恢复最近一次删除的那张表

SQL> show recyclebin;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T4 BIN$OASw9TBNurHgUAB/AQBbYw==$0 TABLE     2016-07-20:05:26:13

T4 BIN$N++H8pxalGbgUAB/AQAvxA==$0 TABLE     2016-07-19:04:08:26

T4 BIN$N+52pkGdHVLgUAB/AQAgTQ==$0 TABLE     2016-07-19:02:52:00

SQL> flashback table t4 to before drop;

Flashback complete.

SQL> show recyclebin;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T4 BIN$N++H8pxalGbgUAB/AQAvxA==$0 TABLE     2016-07-19:04:08:26

T4 BIN$N+52pkGdHVLgUAB/AQAgTQ==$0 TABLE     2016-07-19:02:52:00

如果回收站里的表名有重复,指定要恢复的表,需要使用回收站里的表名

SQL> show recyclebin;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T4 BIN$OASw9TBOurHgUAB/AQBbYw==$0 TABLE     2016-07-20:05:29:27

T4 BIN$N+52pkGdHVLgUAB/AQAgTQ==$0 TABLE     2016-07-19:02:52:00

指定回收站里的名字需要加双引号

SQL> flashback table "BIN$N+52pkGdHVLgUAB/AQAgTQ==$0" to before drop;

Flashback complete.

SQL> show recyclebin;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T4 BIN$OASw9TBOurHgUAB/AQBbYw==$0 TABLE     2016-07-20:05:29:27

清空回收站

SQL> show recycle;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T7 BIN$M1uFYjFnoJrgUAB/AQALVQ==$0 TABLE     2016-05-21:21:59:28

SQL> purge recyclebin;

Recyclebin purged.

SCOTT@ora10g> show recycle; 查看回收站.

SCOTT@ora10g> purge recyclebin; 清空回收站.

SCOTT@ora10g> purge table t2 ; 清空回收站中t2的表.

SQL>  purge dba_recyclebin; 清空所有用户回收站里的内容.

SQL> alter session set recyclebin=off; 关闭当前会话的回收站;

SQL> alter system set recyclebin=off; 关闭系统的回收站;

每个用户分配一个回收站。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 1.简介 数据存储有哪些方式?电子表格,纸质文件,数据库。 那么究竟什么是关系型数据库? 目前对数据库的分类主要是...
    乔震阅读 1,710评论 0 2
  • 5.DML DML 语句 语句操作语言 INSERT UPDATE DELETE MERGE INSERT 方法:...
    乔震阅读 931评论 0 0
  • 幕课oracle学习笔记 --!!!scott用户 --一.分组查询 --1.常用的分组函数:AVG(平均数),S...
    xiaoxiao苏阅读 1,260评论 0 5
  • mysql数据库中 :database : 文件夹table : 数据表(数据文件) 进入mysqlmysql -...
    赋闲阅读 559评论 0 0
  • 风和日丽的季节,当猫咪遇见蜂蜜。 绘画工具材料:砚台,白盘,笔洗,墨,水,毛笔,宣纸,国画颜料。 第一步:用丝毛法...
    马枪月阅读 258评论 0 0