wtxtools

C++博客 首页 新随笔 联系 聚合 管理
  11 Posts :: 8 Stories :: 2 Comments :: 0 Trackbacks

*************************************
**  oracle 学习笔记第二天    **
**  author Ice Xu   (XuBin)    **
**  date  2006-10-31            **
*************************************
where 条件一定是根据某个字段来进行过滤操作.

多表连接操作:
两表没有任何关联时会产生迪卡尔机:
select   first_name , name  from    s_emp , s_dept;
等值连接:
练习一:查看员工的姓名和员工部门号:(要考虑到表中实际数据中空值的影响)
select   first_name ,   name from  s_emp, s_dept   where s_emp.dept_id=s_dept.id;
练习二:每个员工所在的部门和部门所在的地区
select first_name , name   from s_emp, s_dept,  s_region  where  s_emp.dept_id=s_dept.id and s_dept.region_id=s_region.id;
非等值连接:
练习三:找出每个员工和每个员工的工资级别
  select    a.ename , a.sal, b.grade from emp a , salgrade b  where a.sal between b.losal and b.hisal;
  select    a.ename , a.sal, b.grade from  emp a , salgrade b  where a.sal>=b.losal  and  a.sal<=b.hisal;
自连接:
select   first_name   , manager_id   from  s_emp;
查出所有员工的部门领导的名称:( 这种sql会少一条记录,总经理没有被配置上)
select  e.first_name , m.first_name   from s_emp e , s_emp m  where   e.manager_id=m.id;
外连接:(防止空值时,用(+)的一方会模拟一条记录配置另一方)这就称为外连接,一个记录都不能少;
select  e.first_name , m.first_name   from s_emp e , s_emp m  where   e.manager_id=m.id(+);
查看员工分部的部门:
select  distinct(deptno) from emp ;
找出没有员工的部门:(很经典的一个例子,用外连接来解决的标准做法,这是一种方式)
第一步:
select     e.deptno , d.deptno  from emp e , dept d  where  e.deptno(+)=d.deptno;
第二步:
select     e.deptno , d.deptno  from emp e , dept d  where  e.deptno(+)=d.deptno   and   e.deptno is null;

组函数(group function):
group by  分组子句    对分组后的子句进行过滤还可以用having    条件  对分组后的条件进行过滤   where 是对记录进行过滤

avg(distinct | all )求平均值                            
count(distinct | all )统计
max(distinct | all ) 求最大值
min(distinct | all )求最小值
sum(distinct | all )  求和
(所有组函数会忽略空值 , avg   sum只能作用于数字类型)
求有提成员工的提成的平均值;
select    avg(nvl(commission_pct ,0 )  ) from s_emp;
有多少人有提成:
select  count( commission_pct ) from    s_emp ;
count(*)  用于统计记录数:
select   sum(commission_pct)/ count(*)   from     s_emp;
 员工分部在多少个不同的部门:count  默认为作all的动作
 select   count(dept_id)  from s_emp;
 select   count(distinct dept_id) from   s_emp;
 求各个部门的平均工资:group  by  子句也会触发排序
 select  dept_id ,  avg(salary) aa    from    s_emp    group by   dept_id   order by  aa ;
 select  dept_id ,  avg(salary) aa    from    s_emp    group by   dept_id    ;
 注意:group by 子句后面跟有条件只能是查询的结果中的字段,所以我们会人为在结果要加入一些group by  要用的字段
select   region_id , count(*)  from  s_dept 此句会有错
select   max(region_id)  , count(*) from       s_dept;  (强制语法上可以正确,但是不能保证结果也会正确)
求各个部门不同工种的平均工资:
select     dept_id , title,  avg(salary)  from s_emp   group   by dept_id , title  ;
哪些部门的平均工资比2000高:
select    dept_id,  avg(salary) aa  from s_emp   group by (dept_id)    having      avg(salary)>2000;
除了42部门以外的部门的平均工资:
select   dept_id  ,  avg(salary)   from  s_emp  group by (dept_id ) having    dept_id!=42;
select   dept_id  ,  avg(salary)   from  s_emp   where   dept_id!=42  group by (dept_id ) ;(此种sql效率要高,先过滤再计算)
where       单行函数。
having      组函数。
求各个部门的平均工资:
// 这样统计不详细
select    max(d.name) ,  avg (s.salary)   from   s_emp  s,  s_dept  d where    s.dept_id=d.id   group by    d.name; 
//****这问题很经典,为了过 oracle sql 语法关而写max(d.name)  ***
select   max(d.name)  , avg(e.salary)  , max(r.name)  from s_emp e,   s_dept  d ,   s_region  r  where  e.dept_id = d.id  and  d.region_id=r.id group  by   d.id ;

下午:
关于子查询:  Subqueries
找出所有员工中,工资最低的那个员工:( 利用子查询 )
select    first_name,  salary    from s_emp   where   salary = (  select  min(salary)  from s_emp)    ;
//这样写会出错姓名和工资不一致
select max(first_name),  min(salary)  from s_emp;
子查询运行的顺序: 先运行子查询再运行主查询    子查询一般出现在运算符的右边
单值运算符:运算后面只能跟一个值
多值运算符:可以对两个以上的值进行操作
查询谁跟Smith干一样的活:
select   last_name from  s_emp  where last_name='Smith';
//下种写法可能还存在bug,没有考虑到数据的全面性,有潜在性问题
select  last_name  , title  from s_emp   where title =(  select   title  from s_emp  where  last_name='Smith'  )    and  last_name <> 'Smith'  ;
//这种写法才考虑的比较全面
select  last_name  , title  from s_emp   where title   in   (  select   title  from s_emp  where  last_name='Smith'  )    and  last_name <> 'Smith'  ;
使用子查询时应注意:  单行子查询返回多个结果时会有错误    single-row  subquery returns  more  than one value
查出哪些员工的工资比平均工资低:
select    *  from s_emp  where     salary   <  ( select  avg(salary)  from   s_emp)  ;
哪些部门的平均工资比32部门的平均工资要低:
第一步先查出各个部门的平均工资:
select  min(avg(salary  )  ) from   s_emp   group by  dept_id;
第二步再查出哪个部门的工资是最低的:
select    dept_id,  avg(salary)  from  s_emp   group by dept_id   having   avg(salary) =  (select  min(avg(salary)  ) from  s_emp  group by  dept_id ) ;

哪个部门里没有员工:
select   deptno  from    dept    where   deptno   not  in ( select     deptno    from   emp );
哪些人是普通员工:(用子查询形式来做)
select   *   from  s_emp   where   id  not    in (  select  manager_id   from   s_emp);

E--R图  实体关系图entity  relation 
开发流程先进行需求分析,进行系统设计,建表,再进行开发编码,测试最终产品上线试运行。
把软件设计模型转化为数据中的表,设计时要考虑性能的设计

第一范式:最简单的一种建方式,一张表只有一个主键。
第二范式:表的自连接存在原因,一张表,学生表中也有班级的信息。
第三范式:表连接存在的原因,两张表,其中一张表引用其它一张表。

约束:
为了保证数据的一致性,
primary key   (pk)  主键约束       不允许有重复和空值(唯一且非空)
foregin  key   (fk)   外键约束       两张表parent  table      child   table
unique  key   (uk)  唯一可以为空
not   null
数据库设计时的注意:
索引: 为了提高效率而设计的一种与业务无关的
考虑表点用的物理空间:
考虑表之间的关系:
一对多关系: 利用FK+PK实现,多的一方引用外键
一对一关系: 可以利用FK+UK实现,
多对多关系: 通过中间增加一个附加表来实现,附加表利用联合主键来实现,联合起来的主键唯一。


DDL语句:数据库定义语句:
table (表)
view(示图)
sequence(序列号)
index(索引)

创建表语句:
create    table    [schema].表名   (  字段名,   字段类型   约束条件);                    schema   默认就是当前用户,严格来访问表名完整的写法是schema.tablename
数据类型:
表名的命令规则: 首字母为字母,不得超过30个字符
char(size)                定长  不管是否达到最大宽度,都会点最大的宽度。
varchar2(size)         可变长   按实际的字节占用空间
number            所有的数字类型都称为number
number(n, m )  n------n位宽度   m-----小数点后的宽度
number(2,4)小数点后4 位,有效位2位    values(0.0099) 这样可以   values(0.01)这样出错
LONG    2GB   大文本一个表最我只允许定义一个LONG类型(不建议使用)
CLOB    大对象形式存放(在表里只存一个指针)
BLOB     存二进制大对象(声音,图像之类)

default   作用演示:
create  table   test(c1   number    default  10,     c2    number);


约束的演示:
主键约束的定义:
create table   test(c   number  primary key  );     列级约束
create table  test(c  number , primary key(c) )  ; 表级约束
create table   test( c1  number  constraints   pkc1  primary key );   此约束有名字:  pkc1
create table   test(c number , c2  number ,  primary key (c ,c1) )  ; 用表级约束可以实现联合主键
外键约束的定义:(先定义父表,再定义子表)
carete   table     parent(c1 number  primary key );
create   table    child  (c  number primary key ,   c2 number  references parent(c1));
或表级约束定义:
create   table  child( c number primary key ,  c2  number  , foreign key(c2)  references  parent(c1));

on  delete   cascade  (及联删除,删除父表时子表也跟着删除)
on  delete   set   null  (及联删除父表时子表中引用的字段为null)

posted on 2006-11-07 10:42 传统的浪漫 阅读(559) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理