欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据库总结(oracle)

程序员文章站 2022-06-02 15:55:06
...

数据库总结(oracle)

概述

什么是数据库:存储数据的仓库 ,主要用于解决数据的持久化存储

优点:
1.可存储大量数据
2.方便检索
3.保持数据的一致性、完整性
4.安全,可共享

一、表

1、创建表

语法:
create table t_name(
字段1 数据类型1(数据长度),
字段2 数据类型2(数据长度),
字段3 数据类型3(数据长度),

);

代码示例

 create table t_stu(
      sid number(4),
      sname varchar2(20),
      sage  number(2)
   ); 

注意事项:
1)oracle 是不区分大小,数据库在执行sql语句 会把我们的sql 小写转成大写 ;
2)如果表已经存在,不能重复创建;
3)每个字段使用逗号隔开,最后一个字段不加逗号;
4)表的命名规则:t_表名。

2、删除表

语法:

drop table 表名;

代码示例

drop table t_stu;

注:增加 [cascade consistent] 表示不经过缓冲区直接删除。

3、添加字段

语法:

alter table 表名 add 字段名 字段类型;

代码示例

alter table t_stu add ssex varchar2(2);

4、修改字段类型

语法:

alter table 表名 modify 字段 字段类型;

代码示例

alter table t_stu modify ssex number(1);

5、修改字段名

语法:

alert table 表名 rename column 源字段 to 新字段;

代码示例

alter table t_stu rename column  ssex to sex;

6、删除字段

语法:

alter table 表名 drop column 字段名;

代码示例

alter table t_student drop column sex;

7、表和字段的注释

1)表注释

语法:

comment on table 表名 is ‘解释说明’;

代码示例

comment on table t_stu is '学生表';

2)字段注释

语法:

comment on column 表名.字段名 is ‘解释说明’;

代码示例

comment on column t_stu.sid is '学生id';
comment on column t_stu.sname is '学生姓名';
comment on column t_stu.sage is '学生年龄';

二、Oracle中数据类型 .

1、字符型

1)char 字符型[长度固定]

能够存储最大长度是2000 个字节
系统会分配固定长度空间 不会应为数据大小而做出调整 节约计算空间的时间 提高效率

2)varchar2 字符型[长度是可变]
能存存储最大长度是4000字节
相比char 内存利用更高 会计算实际存储长度动态分配内存

3)long 字符型[大型字符]
能存存储最大2G文本.

代码示例

         create table testChar(
          text1 char(4),
          text2 varchar2(4),
          text3 long,
          text4 char);  
     注意: char 可以不给长度 默认是1个长度 varchar2 必须给长度

2、数据型

number 数值型 可以存储小数 可以存储整数
格式: number[(p,s)]
p 整数 s表示小数
number 默认长度是32位 最高精度38位
number(5) 表示整数 长度是5
number(5,2) 表示真整数是(5-2)位 小数2位 如果小数不够补0 如果小 太多了 四舍五入保留2位小数

代码示例

    create table testNumber(
         num1 number,
         num2 number(5),
         num3 number(5,2)
    );

3、时间型

1)date 日期 精确到秒 2019-9-7:11:22:33
timestamp 时间戳 精确到 秒后面的6位 2019-9-7:11:22:33.000000

代码示例

    create table testDate(
       bir date,
       mytime  timestamp
    );

4、大型数据类型

blob 存储大型二进制文件
clob 存储字符文件,类似 long

代码示例

     create table testdata(
         bytefile blob,
         charfile clob
    );

三、约束

1、非空约束

限定某个字段不能为空

语法:

create table 表名(
字段 字段类型 not null
);

代码示例

create table testNull(
   id number(3) not null
);   

2、默认值的约束

如果某个字段没有值 可以设置一个默认值

语法:

create table 表名(
字段 字段类型 deault 默认值
);

代码示例

create table teseDefault(
    name varchar2(10) default '逍遥',
    age number(2) default 18
);

3、唯一约束

表示某个字段值在表中是唯一标识

语法:
create table 表名(
字段 字段类型 unique
);

代码示例

create table testUnique(
   id number(5) unique
);

注意:
1)如果2个数据不为空 唯一约束不相等 (如果都为空数据是 可以插入)

2)一个字段可以加入多个约束

4、主键约束

表示是 设定的字段 是唯一且非空约束

主键是唯一标识符 (加快查询效率 自动创建索引)

语法:

create table 表名(
字段 字段类型 primary key
);

代码示例

    create table testPrimary(
          id number(4) primary key,
          name varchar2(10) default '老宋'
    ); 

补充:

创建表后给 表testKey 添加主键

        create table testKey(
           id number(3),
           name varchar2(20)
        );

alter table 表名 add constraint 主键标识符 primary key(字段名);
alter table testKey add constraint pk_key primary key (id);

联合主键:

多个字段联合起来组成主键
alter table testKey add constraint pk_key primary key (id,name);

注意:
1)主键是唯一标识 一张表 只能有一个主键 ;

2)多个字段联合为一个联合主键 ;

3)一张表可有多个 unique + not null,但是只能有一个主键。

5、外键约束

外键是从表中重复出现,在主表中作为主键存在 外键关联2张表

主表: 主键的表 一方
**从表:**外键的表 多方

实现例子例如:

班级 主表 一方 员工 多方
学生 从表 多方 部门 一方

多方关联一方 多方设置外键

Java中的对象模型:

class Student{
     private int sid;
     private String name;
     private int ClassId;
       
 }   
 
 class Calss(
   private int Classid;
   private String className;
 );

数据库中的模型:

方式一,表内添加

-- 从表
create table t_stu(
     sid number(3),
     sname varchar2(20),
     classId number(4)constraint fk_stu_class foreign key (classId) references t_class(cid)
);

constraint fk_stu_class foreign key (classId) 把 字段 classId声明为外键,references t_class(cid)关联其他表的字段

   -- 主表
   create table t_class(
       cid number(4) primary key,
       cname varchar2(10)
   );

方式二,现有表添加外键 ()

alter table t_stu add constraint fk_stu_class foreign key(classId) references t_class(cid);

外键的特点:
1)外键可以在从表中重复出现 ,他在主表中是主键
2)一张表可以有多个外键
3)外键可以为null
4) 外键的作用是关联多种表,可以建立表之间的关系 (一对一 一对多 多对多)
5)删除主表时候 如果 从表有使用主表的数据 是不能删除的, 从表的数据可以直接删除
6)2表关联了 先删除 从表 在删除主表
7)关键是多表查询单 必要条件

6、check约束

某个字段可以在一定的设置范围存储

check 约束可以给字段加运算符和一些关键字:

· >, < ,= ,and, or, in / not in , is null / is not null

代码示例

   create table t_stu(
       sage1 number(2) check(sage>20)     
       sage2 number(2) check(sage = 18 or sage=20)   
       sage3 number(2) check(sage in (18,19,20))
   );
-- 建表以后如何添加check约束 
	alter table t_stu add constraint ck_stu_age check(sage4 in (18,19,20));  

四、DML(数据操纵语言)

1、简述

数据操纵语言用于插入、修改和删除数据,数据操纵语言是最常用的SQL命令

2、insert

插入操作:表中出入一行数据

1)方式一

语法:
insert into 表名(字段1,字段2…) values(val1,val1 …);

注意:字段与值一一对应

代码示例

     create table t_stu(
             sid number(2),
             sname varchar2(20),
             sage number(2)
    );    
    
    insert into t_stu(sid,sname,sage) values (1,'慕容复'20);
    insert into t_stu(sid,sname,sage) values (2,'王语嫣'20);
    insert into t_stu(sid,sname) values (3,'虚竹');
    commit;

2)方式二
插入所有的字段的时候 可以省略字段名
insert into 表名 values (val1,val2…)
insert into t_stu values (3,‘段正淳’,50);

代码示例

  create table t_stu_copy(
     sid number(2),
     sname varchar2(20),
     sage number(2)
  );

补充

插入多条记录
– 把 t_stu 表中数据查出来 插入到 t_stu_copy
insert into t_stu_copy(sid,sname) select sid,sname from t_stu;

– 复制表
复制表结构和数据
create table t_stu_copy1 as select * from t_stu;

仅仅复制表结构
– where 1 != 1 不把数据查出来
create table t_stu_copy2 as select * from t_stu where 1 != 1;

3、update

语法:
update 表名 set 字段1= val1,字段2=val2 where 判断条件;

代码示例

    create table t_person(
      pid number(2),
      pname varchar2(20),
      page number(2)
    );
     insert into t_person(pid,pname,page) values (1,'乔峰',45);
     insert into t_person(pid,pname,page) values (2,'段誉',35);
     insert into t_person(pid,pname,page) values (3,'段正淳',42);
     insert into t_person(pid,pname,page) values (4,'丁春秋',60);
     insert into t_person(pid,pname,page) values (5,'无崖子',70);
     commit;
     -- 修改 pid=1 数据 
     update  t_person set pname = '王语嫣' where page = 45;
     
     -- 修改多条数据   or 或者 in 

      update  t_person set pname = '秦红棉' where pid = 2 or pid = 3;
      update  t_person set pname = '李秋水',page = 33 where pid in (3,4);
     
      -- 没有给判断条件 ,会修改所有数据
      update  t_person set pname = '王语嫣';
      
     - 注意:  修改的时候一定要把加  where判断条件  

4、delete

语法:

delete from 表名 where 条件;

代码示例

   -- 通过id删除 
   delete from t_person where pid = 1;
    -- 删除需要带条件 
   delete删除 先将删除的数据放在内存中 执行commit 才是删除数据库 
   
   --truncate 也 可以删除数据 这种删除是不经过内存 直接删除 

5、select

1)基本查询:

语法:

select * from 表名; 查询所有的字段
select 字段 as [别名] from 表名; 查询一些字段

代码示例(系统自带表 emp)

 -- 查询所有的员工信息 
        select * from emp;
        -- 查询编号,姓名 职位  薪资 
        select empno,ename,job,sal from emp;
        
        -- 查询结果显示标题 (编号,姓名 职位  薪资)
        -- as 添加别名  ("员工编号")
        -- as 可以省略   "" 可以省略 
         select empno as "员工编号" ,ename 姓名,job,sal from emp;
        
        -- 查询所有emp 的职位 
        select job from emp; -- 有重复 去重复
        -- 去重复  distinct
        select distinct job from emp;
        
        -- 查询中进行四则运算  查员工年薪 
        select ename,job,(sal * 12 + 200) 年薪 from emp;
     
        -- 查询常量的使用 
         select '员工',ename,job from emp; -- 可以是字符串 常量 
         select 9527,ename,job from emp;  -- 可以是数组常量 (省略 '')
         
        -- 可以使用 || 凭借符  合并列
        select empno || ename from emp;
        
        -- 查询的时候 表 可以使用别名 ,一般别名生成在表后    表名 别名
        select e.ename,e.job from emp e;

2)条件查询

语法:

select 列名 from 表名 where 判断条件;

代码示例

	 --1. 关系运算符  > =    (<> !=) 不等于两种写法 
      --sal > 1500 员工 
      select * from emp where sal > 1500;
      --名字叫soctt 的员工信息
      select * from emp where ename = 'SCOTT';
      
      --职位不是 ANALYST 的员工 
      select * from emp where job <>'ANALYST';
      select * from emp where job !='ANALYST';
     
     --2. 逻辑运算符  and  or not 
      --sal 在 1500 -2000 之间的  
      select * from emp where sal > 1500 and sal < 2500;
      
      --查询sal > 3000 或者 名字叫 SCOTT 
        select * from emp where sal > 3000 or ename = 'SCOTT';
      
      --SAL 不在这个 1500 -2000
       select * from emp where not (sal > 1500 and sal < 2500);      
     
    --3.区间运算 
      --between ... and ...  可以用在 数值 和 时间上 
      --1) 查找在 1200 到 2500 之间 
       select * from emp where sal between 1200 and 2500;
      --2) 在 1981 年入职的员工   
       select * from emp where hiredate between '01-1月-81' and '30-12月-81';
     
    --4. 判断 null 操作 
       --is null  is not null 
       
       -- 奖金为null 的员工 comm 是奖金 
       select * from emp where comm is null;
       -- 不为空 
       select * from emp where comm is not null;
       
    --5. in   和  not in  
    
        --在in 什么中 
         --判断员工标号 :是否在 (7499,7521,8888) 
        select * from emp where empno  = 7499 or empno = 7521 or empno  =8888;
        select * from emp where empno in (7499,7521,8888);

3)模糊查询

语法:

select 列名 from 表名 where 字段名 like ‘字符串’;

通配符的解释: _ 代表匹配一位 , % 匹配 0 -多位

   1.查以 姓名以 A开头的员工 
   select * from emp where ename like 'A%';  
   2.以s结尾  
    select * from emp where ename like '%S';  
   3. 查询 第二字符为A的官员 
   select * from emp where ename like '_A%';
   4. 是否包含s的员工 
   select * from emp where ename like '%S%';

4)排序查询
语法:

select * from t where 条件 order by 字段;

代码示例

    -- sql的执行顺序 
    --1.查表名 
    --2.查询 where判断条件 
    --3.select *  字段
    --4.排序   ASC 升序(默认是升序),desc 降序
  
 1.查询所有的员工 
 
 select * from emp; -- 通过插入顺序进行 展示的 

 -- 通过薪资进行排序 (底到高) 升序 
   select * from emp
   order by sal ASC;
 --  默认是升序  asc 可以省略 
  select * from emp
   order by sal desc;
 
 -- 按照入职时间进行排序(升序) 如果入职时间相同 薪资排序 (降序)
 
 select * from emp order by hiredate asc,sal desc;

五、函数

1、单行函数:

对每一个函数应用在表的记录中时,只能输入一行结果,返回一个结果,
比如:MOD(x,y)返回x除以y的余数(x和y可以是两个整数,也可以是表中的整数列)。

常用的单行函数有:
字符函数:对字符串操作。
数字函数:对数字进行计算,返回一个数字。
转换函数:可以将一种数据类型转换为另外一种数据类型。
日期函数:对日期和时间进行处理。

2、聚合函数

聚合函数同时可以对多行数据进行操作,并返回一个结果。比如SUM(x)返回结果集中x列的总合。

常用的聚合函数有

SUM(x); 返回该列的和

MAX(x);返回该列的最大值

MIN(x);返回该列的最小值

AVG(x);返回该列的平均值

COUNT(x);返回该列非空值行数

3、字符函数

常见的函数有
ASCII(x) 返回字符x的ASCII码。
CONCAT(x,y) 连接字符串x和y。
INSTR(x, str [,start] [,n) 在x中查找str,可以指定从start开始,也可以指定从第n次开始。
LENGTH(x) 返回x的长度。
LOWER(x) x转换为小写。
UPPER(x) x转换为大写。
LTRIM(x[,trim_str]) 把x的左边截去trim_str字符串,缺省截去空格。
RTRIM(x[,trim_str]) 把x的右边截去trim_str字符串,缺省截去空格。
TRIM([trim_str FROM] x) 把x的两边截去trim_str字符串,缺省截去空格。
REPLACE(x,old,new) 在x中查找old,并替换为new。
SUBSTR(x,start[,length]) 返回x的字串,从staart处开始,截取length个字符,缺省length,默认到结尾。

4、数字函数

函数 说明
ABS(x) x绝对值 ABS(-3)=3
ACOS(x) x的反余弦 ACOS(1)=0
COS(x) 余弦 COS(1)=1.57079633
CEIL(x) 大于或等于x的最小值 CEIL(5.4)=6
FLOOR(x) 小于或等于x的最大值 FLOOR(5.8)=5
LOG(x,y) x为底y的对数 LOG(2,4)=2
MOD(x,y) x除以y的余数 MOD(8,3)=2
POWER(x,y) x的y次幂 POWER(2,3)=8
ROUND(x[,y]) x在第y位四舍五入 ROUND(3.456,2)=3.46
SQRT(x) x的平方根 SQRT(4)=2
TRUNC(x[,y]) x在第y位截断 TRUNC(3.456,2)=3.45

1)ROUND(X[,Y]),四舍五入。
在缺省y时,默认y=0;比如:ROUND(3.56)=4。
y是正整数,就是四舍五入到小数点后y位。ROUND(5.654,2)=5.65。
y是负整数,四舍五入到小数点左边|y|位。ROUND(351.654,-2)=400。

select round(3.26) from dual; – 保留整数 dual表示伪表
select ROUND(5.655,2) from dual; – 保留2位小数
– 日薪
select ename,sal,round(sal / 30,1) 日薪 from emp;
select ROUND(341.654,-2) from dual;

2)TRUNC(x[,y]),直接截取,不四舍五入。
在缺省y时,默认y=0;比如:TRUNC (3.56)=3。
y是正整数,就是四舍五入到小数点后y位。TRUNC (5.654,2)=5.65。
y是负整数,四舍五入到小数点左边|y|位。TRUNC (351.654,-2)=300。

select TRUNC(5.654) from dual; – 截取去除小数后面的
select TRUNC(5.658,2) from dual;
select TRUNC(351.654,-2) from dual;

5、日期函数

1)ADD_MONTHS(d,n),在某一个日期d上,加上指定的月数n,返回计算后的新日期。d表示日期,n表示要加的月数。
select add_months(sysdate, 12) from dual;

2)LAST_DAY(d),返回指定日期当月的最后一天。
select LAST_DAY(sysdate) from dual;

3)ROUND(d[,fmt]),返回一个以fmt为格式的四舍五入日期值,d是日期,fmt是格式模型。默认fmt为DDD,即月中的某一天。
如果fmt为“YEAR”则舍入到某年的1月1日,即前半年舍去,后半年作为下一年。
如果fmt为“MONTH”则舍入到某月的1日,即前月舍去,后半月作为下一月。
默认为“DDD”,即月中的某一天,最靠近的天,前半天舍去,后半天作为第二天。
如果fmt为“DAY”则舍入到最近的周的周日,即上半周舍去,下半周作为下一周周日。

  select sysdate, round(sysdate), 
                  round(sysdate, 'YEAR'), 
                  round(sysdate, 'MONTH'),
                  round(sysdate, 'DDD'),
                  round(sysdate, 'DAY') FROM DUAL;

4)EXTRACT(fmt FROM d),提取日期中的特定部分。
fmt为:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND。
其中YEAR、MONTH、DAY可以为DATE类型匹配,也可以与TIMESTAMP类型匹配;
但是HOUR、MINUTE、SECOND必须与TIMESTAMP类型匹配。

SELECT EXTRACT(YEAR FROM SYSDATE),
       EXTRACT(MONTH FROM SYSDATE) ,
       EXTRACT(DAY FROM SYSDATE) ,
       EXTRACT(HOUR FROM SYSTIMESTAMP) ,
       EXTRACT(MINUTE FROM SYSTIMESTAMP) ,
       EXTRACT(SECOND FROM SYSTIMESTAMP)  FROM DUAL;
  -- 查看 我们的emp的员工的工龄  (当前的事件 - 入职时间)

   select ename,job,hiredate from emp;

   -- 哪一年入职
   select ename,job,hiredate,EXTRACT(YEAR from hiredate) from emp;
   -- 查看工龄
    select ename,job,hiredate,EXTRACT(YEAR from Sysdate) - EXTRACT(YEAR from hiredate) from emp;
    
-- 查看二月份入职的员工  获取月份 
 select ename,job,hiredate from emp
 where extract(MONTH FROM hiredate) = 2;

6、日期装换函数

to_date : 将字符串转换成日期

to_char : 将日期转换成字符串

注意:
yyyy表示四位年份
mm表示两位月份
dd表示两位天数
hh24表示24小时,hh12表示12小时
mi表示分钟
ss表示秒钟
select sysdate,
to_char(sysdate,‘yyyy/mm/dd hh:mi:ss’),
to_char(sysdate, ‘yyyy-mm-dd’),
to_char(sysdate, ‘yyyy-mm’),
to_char(sysdate, ‘yyyy’)
from dual;
注意 sql 中字符串是数字 可以进行运算

     -- 工龄的计算 
    select ename,job,hiredate from emp;
    
    select ename,job,hiredate,to_char(hiredate,'yyyy') 入职年份 from emp;
    
    -- 工龄
    select ename,job,hiredate,(to_char(sysdate,'yyyy') - to_char(hiredate,'yyyy')) 工龄 from emp;    

7、其他函数

1)nvl(column, value) 如果column为空,返回value,否则返回x。

   -- 查看 奖金 
   select ename,job,sal,comm from emp;

   -- 查看总工资 
    select ename,job,sal + comm 月收入 from emp;
   -- 有的人没有工资  (sal + comm ) 如果comm为null  结果为null  不合理 

   --使用nvl 函数 nvl(x,y) x如果为null 可以设置值 y
     select ename,job,sal,nvl(comm,0) from emp;
	-- 查看收入 
    select ename,job,sal + nvl(comm,0) 月收入 from emp;

2)decode: 类似于Java当中 if 、 if else、if else if else

     create table stu(
        sid number(2),
        sname varchar2(20),
        ssex number(1)
     );
	select sid,sname,ssex
       , decode(ssex, 1, '女') 
       , decode(ssex, 1, '女', 2, '男')
       , decode(ssex, 1, '女', 2, '男','未知')        
     from stu;   

六、多表查询

1、合并结果集

合并结果集
union 去除重复并且合并
union all 不去重复的记录

技巧: 要求合并的多个结果集中 列的类型和 列的数量必须相同

   create table test1(
      tid number(2),
      tname varchar2(20)
   );
   insert into test1 values(1,'a');
   insert into test1 values(2,'b');
   insert into test1 values(3,'c');
   commit;
   
   create table test2(
      did number(2),
      dname varchar2(20)
   );
   insert into test2 values(3,'c');
   insert into test2 values(4,'d');
   insert into test2 values(5,'f');
   commit;

​ 把查询 结果 合并成一个集

    -- 结果集去除重复的  union 
   select * from test1 union select * from test2;
   
   -- 结果集不去除重复  union all 
   select * from test1 union all select * from test2;

2、连接查询

1)交叉连接

查出的员工的 部门信息
查表:
emp 字段 所有
dept 字段 所有
select * from emp; – 15 条数据
select * from dept;-- 4 条数据

  select * from emp,dept;

交叉查询的问题:
会产生很大的结果集(15 * 4 ) 60 性能低

结果集 有一些数据对我们没意义

2)等值连接

在交叉查询的基础上 加上条件 (表与表之间的 关联字段 deptno )
添加 条件 加关联字段 deptno

   select * from emp,dept where emp.deptno = dept.deptno; 
   --(查询的时候 还是产生了60条数据  通过过滤显示解决没有意义的数据)
3)内连接

a inner join b on (关联字段)

  select * from emp inner join dept on (emp.deptno = dept.deptno);
   --表使用别名:
  select * from emp e inner join dept d on (e.deptno = d.deptno);  
   --解决了查询 结果集 数据太多的问题

问题: 数据不全 (两个表对应不上的数据不会显示)

4)外连接

左外连接:把左表所有数据查询出来

右外连接:把右表所有的数据查出来

全外连接 : 把俩表所有的数据查出来

自然连接: 会多表联查 自己给我们关联数据(了解)

  --左外连接
  select * from emp e left join dept d
      on e.deptno = d.deptno; 
      
  --右外连接
  select * from emp e right join dept d
  on e.deptno = d.deptno;  
  
  --全外连接
   select * from emp e full join dept d on e.deptno = d.deptno; 
   
  --自然连接
   select e.ename,d.dname from emp e natural join dept d; 

oracle 方言查询:

于外连接,也可以使用“(+)”来表示。但须注意:

  1. (+)操作符只能出现在where子句中,并且不能与outer join语法同时使用
  2. 当使用(+)操作符执行外连接时,如果在where子句中包含有多个条件,则必须所有条件中都包含(+)操作符
  3. (+)操作符只适用于列,而不能用在表达式上
  4. (+)操作符不能与or和in操作符一起使用
  5. (+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接

用(+)来实现,这个+号可以这样来理解:+ 表示补充,即哪个有+,这个表就是匹配表,另外的则是基础表。

select t1.c1,t2.c2 from t1,t2 where t1.c=t2.c(+)    --左连接
select t1.c1,t2.c2 from t1,t2 where t1.c(+)=t2.c    --右连接
   左外连接:
   select * from emp e,dept d where e.deptno = d.deptno(+);  
   右外连接:
   select * from emp e,dept d where e.deptno(+) = d.deptno;

99sql写法:  [JOIN 表名称 ON(条件)|USING(字段)] 
select * from emp e left join dept d using(deptno);
5)分组查询

语法

select * from t
where 条件
group by 分组字段
order by 排序字段
having 分组后刷选字段;

代码示例

--统计出部门的平均工资高于 2000的 部门的详细信息(部门编号、部门名称、部门位置、部门人数、部门平均薪资)。
  select d.deptno,d.dname,d.loc,count(e.empno),avg(e.sal) 
    from emp e right join  dept d 
    on d.deptno = e.deptno
    group by d.deptno,d.dname,d.loc
    having avg(e.sal) > 2000;

七、序列

序列 是oracle 独有的 用来结果我们的插入实现主键自动增长的操作

--创建序列的语法:
create sequence SEQ_STU
minvalue 1  --  最小是 1
maxvalue 9999 -- 最大 
start with 2  -- 开始位置 
increment by 1 -- 增量 
cache 20;   -- 缓存大小 

-- 序列的使用方式:
 --  nextval:  获取下一值的序列 
 --  currval;  获取当前会话的序列
-- 结合 插入语句使用 序列: (实现 表的主键字段自动增长)
  -- dual (伪表 专门用来写测试sql 的一些语句)
   select seq_stu.nextval from dual; -- 6
   select seq_stu.currval from dual;-- 6 
   
   create table t_stu(
     sid number(2) primary key,
     sname varchar2(20),
     sage number(2)
   )  
   SEGMENT CREATION IMMEDIATE;
   
   insert into t_stu(sid,sname,sage) values (seq_stu.nextval,'鸠摩智',45);

--问题?  插入的序列从 2开始 ? 
--Oracle从 11.2.0.1版本开始,提供了一个“延迟段创建”特性:即
 -- 当我们创建了新的表(table)和序列(sequence),
--  在插入(insert)语句时,序列会跳过第一个值(1)。
--  所以结果是插入的序列值从 2(序列的第二个值) 开始, 而不是 1开始。   
 --解决办法:
-- 创建表时让seqment立即执行,
 SEGMENT CREATION IMMEDIATE;
 
 --注意: 
  -- 1.每次执行序列 会自动增长
 --  2.序列本身是一个变化的数据  可以独立使用 可以交互使用(不建议交互使用)
 --  3 nextval 获取下一序列  currval 获取当前的序列  从新开始了一个会话 不能获取 当前会话序列--(currval) 需要先获取下一个序列  才可以 currval
  -- 4. 创建序列时候 默认从2开始  解决(创建表的时候  添加 SEGMENT CREATION IMMEDIATE)