42,數據庫(04)

/*
 達內學習 Oracle day41 2013-10-29*/
組函數 和 分組
1.處理特點
  對一組數據處理返回一個結果
2.常見的組函數
  count   max  min  avg  sum
3.組函數可以使用 distinct
4.組函數對 NULL 處理是忽略

分組
1.按照一定的分組標準 把數據分成若干組
2.group by  分組標準
3.如何組數據進行過濾  having
4.sql的執行順序
  from 
      where
           group by
         having
      select
          order by
5.分組中結合表連接
  在分組語句中select 後字段的限制
  要麼是分組標準  要麼是經過合適的組函數
  處理過的。
----------------------------------
子查詢:
    把一個查詢的結果  作爲另一個查詢的
    基礎。
1.where 後
  select  distinct  manager_id from s_emp;
  select  id ,first_name from s_emp
      where  id in(select  distinct 
      manager_id from s_emp);
2.having  後
3.from   後
 select *from(select dept_id id,avg(salary) sal
      from  s_emp
         group by dept_id)where sal>
  (select avg(salary) from s_emp
   where dept_id=42);
-------------------------------------
DDL
1.建表語句
  create table  表名(
      字段名     類型,
      字段名     類型,
      字段名     類型
  );
2.刪表語句
  drop  table  表名 ;
3.數據類型
  number
  char
  varchar2
4.date 類型
  1.默認格式   'dd-MON-yy'
  2.沒有時分秒信息
    如果採用默認格式插入的 時分秒都是0
  3.to_char  以指定格式顯示日期
    yyyy
    mm
    dd

    hh24
    mi
    ss

    mon
    month
    day
    pm
  4.把日期的時分秒放入數據庫
    sysdate
    to_date(日期字符串,日期格式字符串)
  5.按照天  小時  分鐘 秒 爲單位進行調整
  6.特殊調整
    add_months
    last_day
    next_day
  7.日期的計算
    months_between
    round
    trunc
------------------------------------
DML   和 事務控制
1.insert 
  insert  into  表名 values(值1,值2);
  insert  into  表名(字段1,字段3)
  values(值1,值3);
2.delete
  delete from  表名 where 條件;
3.update 
  update 表名  set 字段=值1,字段2=值
      where 條件;
DML操作 是有事務特性的。
事務 也叫交易  transation
原子性:事務中的操作 是一個不可的整體
    一起成功 一起失敗
    轉賬
    update account set money=money-5000
        where id='A';
    -- commit;
    /* commit;*/
    update account set money=money+5000
        where id='B';
    if(a&&b){
        commit;
    }else{
        rollback;
    }
    create table  account(
        id     varchar2(10) primary key,
        money  number
    );
    insert  into account values('A',10000);
    insert  into account values('B',1);
    commit;
隔離性:事務中的操作 再沒有提交以前 對
    另一個事務數據的變化是不可見的。
    但事務會鎖定這條數據,沒提交以前
    別的事務對同樣的數據做操作會產生
    鎖定狀態。
    insert  into  account values
    ('C',99999999);
    commit;
    rollback; 只能撤銷未提交的數據。
     insert  into  account values
    ('D',89999999);
一致性
持久性

--------------------
事務的原子性太嚴格,有時要做部分成功 部分
失敗。
insert  into  account  values('E',1);
savepoint   a;
insert  into  account  values('F',2);
savepoint   b;
insert  into  account  values('G',3);

rollback to b;
commit;

--------------------------------------
數據庫中的約束:constraints
對數據庫表中的字段加的限制。
1.五種具體的約束
  a.主鍵約束    primary  key
    非空 並且 唯一
    一個表的主鍵只能有一個
  b.唯一性約束  unique
    值不能重複
  c.非空約束     not null
    值不能是NULL值
  d.檢查約束     check
    表中字段的值 必須符合檢查條件
  e.外鍵約束     references(關聯引用)
                 foreign key
2.表中約束的分類
  a.列級約束
    在定義表的某一列時 直接對錶的這一列
    加約束限制。
  b.表級約束
    在定義完表的所有列之後 再選擇某些列
    加約束限制。
3.主鍵的列級約束
  create  table  testcol_cons(
      id   number primary key,
      name  varchar2(30)
  );
  insert into testcol_cons values(1,'a');
  insert into testcol_cons values
  (NULL,'b');
  insert into testcol_cons values(1,'c');
  ERROR at line 1:
  ORA-00001: unique constraint
  (OPENLAB.SYS_C00360658)
  如果給一個加約束 沒有起名字 則系統會
  爲這個約束自動建立一個名字。
 4.建立字段的約束時  自己給約束命名
   pk  uk   nn  ck  fk
   drop    table  testcol_cons111;
   create  table  testcol_cons111(
      id   number constraint
      testcol_cons111_id_pk primary key,
      name  varchar2(30)
   );  
   insert into testcol_cons111
   values(1,'c');
   insert into testcol_cons111
   values(1,'c');
   ERROR at line 1:
ORA-00001: unique constraint (OPENLAB.TESTCOL_CONS111_ID_PK) violated

  5.主鍵約束 和 唯一性約束的列級約束
   建立一張表
   id      number   設置成主鍵
   fname   varchar2(30) 設置成唯一
   要求給每個約束起名字。
   drop    table  testcol_cons111;
   create  table  testcol_cons111(
      id   number constraint
      testcol_cons111_id_pk primary key,
      fname  varchar2(30) constraint
      testcol_cons111_fname_uk unique
   ); 
   insert into testcol_cons111 values
   (1,'test');
   insert into testcol_cons111 values
   (2,'test');
   insert into testcol_cons111 values
   *
   ERROR at line 1:
   ORA-00001: unique constraint
   (OPENLAB.TESTCOL_CONS111_FNAME_UK)
   violated

   6.建立一張表 
     id     number  primary  key
     fname  varchar2(30)  unique
     sname  varchar2(30)  not null
     salary  number   檢查條件
                      salary>3500
     create  table testcolucons(
         id   number constraint
         testcolucons_id_pk  primary key,
  fname varchar2(30) constraint
  testcolucons_fname_uk unique,
  sname  varchar2(30) constraint
  testcolucons_sname_nn not null,
         salary number       constraint
  testcolucons_salary_ck
  check(salary>3500)
     );
    insert into testcolucons values
    (1,'test','test',3499);
    ERROR at line 1:
    ORA-02290: check constraint
    (OPENLAB.TESTCOLUCONS_SALARY_CK)
    violated
  7.表級約束的主鍵約束
    在定義完表的所有列之後 再選擇某些
    列加約束限制。
    表級約束的優勢在於可以做聯合約束。
    在數據庫中 沒有聯合非空的需求
    導致非空沒有表級約束。
    create table  testtable_cons(
        id   number,
        fname  varchar2(30),
 sname  varchar2(30),
 salary number,
 constraint testtable_cons_id_pk
 primary key(id)
    );
  8.唯一性  和 檢查約束的表級約束
    drop   table  testtable_cons;
    create table  testtable_cons(
        id   number,
        fname  varchar2(30),
 sname  varchar2(30),
 salary number,
 constraint testtable_cons_id_pk
 primary key(id),
 constraint testtable_cons_fname_uk
 unique(fname),
        constraint testtable_cons_salary_ck
 check(salary>3500)
    );
---------------------------------------
外鍵約束:涉及到兩張表 一張叫父表(主表)
另一張叫子表(從表)。
子表中一個字段 稱之外鍵  外鍵字段的取值
受限於父表的字段值。
外鍵的取值 要麼是NULL  要麼是父表中字段
的取值。
定義了外鍵的表就是子表。
create  table  parent(
    id   number   primary  key,
    name  varchar2(30)
);
create  table  childtest(
    id   number   primary  key,
    name  varchar2(30),
    fid  number constraint
    childtest_fid_fk
    references  parent(id)
);
insert into childtest values(1,'test',1);
RROR at line 1:
RA-02291: integrity constraint
(OPENLAB.CHILDTEST_FID_FK)
1.建立表  先建立父表 後建立子表
  除非先不考慮主外鍵關係
2.插入數據一般先插入父表 後插入子表數據
  除非子表的外鍵值是NULL
3.刪除數據
  先刪子表數據 後刪父表數據
  除非子表中沒有和主表字段對應的數據
  或者設置了級聯(on delete cascade
                 on delete set null)
4.修改數據  設置外鍵的值 要麼爲NULL
  要麼設置成父表中字段對應的值
5.刪除表
  先刪子表  後刪父表
  除非你使用先解除主外鍵關係 再刪除表
  drop table  parent;
  drop table  parent cascade constraints;
舉例:
部門表
create  table  deptparent133(
    id    number  primary key,
    name  varchar2(30)
);
insert into deptparent133 values(1,'test');
insert into deptparent133 values(2,'project');
commit;
員工表  子表
dept_id
create  table empchild133(
    id    number   primary  key,
    name  varchar2(30),
    dept_id  number  constraints
    empchild133_dept_id_fk  references
    deptparent133(id)
);
部門1中有三個員工
部門2中有二個員工
insert into  empchild133 values(1,'a',1);
insert into  empchild133 values(2,'b',1);
insert into  empchild133 values(3,'c',1);
insert into  empchild133 values(4,'d',2);
insert into  empchild133 values(5,'e',2);
commit;
取締一個部門
delete  from  deptparent133 where id=1;
先刪子表和父表字段關聯的數據
delete  from  empchild133  where
dept_id=1;
--------------------------------
/*設置級聯*/
部門表
drop    table  deptparent133
cascade constraints;
create  table  deptparent133(
    id    number  primary key,
    name  varchar2(30)
);
insert into deptparent133 values(1,'test');
insert into deptparent133 values(2,'project');
commit;
員工表  子表
dept_id
drop    table empchild133 cascade
constraints;
create  table empchild133(
    id    number   primary  key,
    name  varchar2(30),
    dept_id  number  constraints
    empchild133_dept_id_fk  references
    deptparent133(id) on delete set null
);
部門1中有三個員工
部門2中有二個員工
insert into  empchild133 values(1,'a',1);
insert into  empchild133 values(2,'b',1);
insert into  empchild133 values(3,'c',1);
insert into  empchild133 values(4,'d',2);
insert into  empchild133 values(5,'e',2);
commit;
取締一個部門
delete  from  deptparent133 where id=1;

--------------------
外鍵的表級約束
drop    table empchild133 cascade
constraints;
create  table empchild133(
    id    number   primary  key,
    name  varchar2(30),
    dept_id  number,constraints
    empchild133_dept_id_fk
    foreign key(dept_id) references
    deptparent133(id) on delete set null
);
--------------------------------------
數據庫的其它對象
1.序列
  生成主鍵的值
  創建序列
  create  sequence  序列名;
  create  sequence  testseq123;
  測試序列
  select  testseq123.nextval from dual;
  select  testseq123.currval from dual;
  使用序列
  create table testpkuse_seq(
      id   number  primary  key,
      name  varchar2(30)
  );
  insert into testpkuse_seq values
  (testseq123.nextval,
  'test'||testseq123.currval);

  複雜的序列
  CREATE SEQUENCE s_customer_id
   MINVALUE 1
   MAXVALUE 9999999   1.0*10 27
   INCREMENT BY 1
   START WITH 216
   NOCACHE             默認20
   NOORDER
   NOCYCLE;
  CREATE SEQUENCE s_customer_idt
   MINVALUE 100
   MAXVALUE 9999999
   INCREMENT BY 1
   START WITH 216
   NOCACHE
   NOORDER
   NOCYCLE;
  select  s_customer_idt.nextval
  from dual;
   刪除序列
   drop  sequence  序列名;
   drop  sequence  s_customer_idt;
----------------------------------------
2.索引
  用來加速查詢
  消耗了大量的空間和時間
  3億條數據   7-8分鐘
  建立索引   消耗了大量的空間和時間
              0.01秒0.00
  如何建立索引
  1.唯一性字段上系統會自動建立索引
    唯一性索引
  2.在非唯一性字段上 可以人爲的創建
    索引。
    create   index  索引名  on
    表名(字段);
    set  timing on;
    create table  testemp101 as
    select id,salary from s_emp;
    create  index  testemp101_id_ind
    on  testemp101(id);
  3.刪除索引
    索引和表佔不是一個空間
    drop  index  索引名;
    drop  index  testemp101_id_ind;
3.視圖
  視圖本質上是一條sql  相對於視圖對應
  的數據 視圖的空間是可以忽略的。
  create  or  replace view  myview
  as select id,first_name,salary from
  s_emp;
  create  or  replace view  myview2
  as select id,first_name from
  s_emp; 
  可以對同一份物理數據 做不同的表現
  簡化查詢
  select * from myview;
  select * from (select id,first_name,
  salary from s_emp);
  select * from myview2;
---------------------------------------
三範式:
  第一範式:表中的字段不可再分
      任何的關係型數據庫必須滿足第一範式
  第二範式:滿足第一範式的基礎上
      所有的非主屬性 完全依賴主屬性
      表中的數據 可以被唯一區分 
  第三範式:在第二方式的基礎上消除了傳遞
      依賴。
一張表 能不能表達1:m?
一個部門中有多個員工
id  did  dname  eid  ename eage
1   d001 test   e001 ea    19
2   d001 test   e002 ea    21
3   d001 test   e003 ec    20
4   d002 ios    e004 ed    23
5   d002 ios    e005 ee    26

好處 方便查詢
壞處 數據冗餘
     增 刪 改
消除傳遞依賴  -----拆表
id->did->dname
id->eid->did->dname
id->eid->ename
拆分出部門表
did  dname
d001 test
d002 ios
拆出員工表
eid  ename eage  did
e001 ea    19    d001
e002 ea    21    d001
e003 ec    20    d001
e004 ed    23    d002
e005 ee    26    d002
如果要做 1:1 只要把did 設置成唯一

一張表 表達多對多
學生選課
id   sid   sname  sage cid cname ctime
1    s001  yangmi 32   c001 c     15
2    s001  yangmi 32   c002 c++   8
3    s001  yangmi 32   c003 ios   35
4    s002  xiaobei44   c001 c     15
5    s002  xiaobei44   c004 vc    35
6    s003  xlong  53   c001 c     15
拆表
學生選課關係表
id   sid      cid
1    s001     c001
2    s001     c002
3    s001     c003
4    s002     c001
5    s002     c004
6    s003     c001

學生表
sid   sname  sage
s001  yangmi  32
s002  xiaobei 44
s003  xlong   53
課程表
 cid cname ctime
 c001 c     15
 c002 c++   8
 c003 ios   35
 c004 vc    35

 s001號 學生選了哪些課程
 select distinct s.sname,c.cname 
     from  student s,course c,stucour sc
         where s.sid=sc.sid and 
        c.cid=sc.cid and
        s.sid='s001';
--------------------------------------
分頁技術:
    oracle   rownum
    mysql    limit
    sqlserver top

select  id,first_name,salary
from s_emp;
select  rownum,first_name,salary
from s_emp;
假設一頁顯示7條 要第一頁數據
select  rownum,first_name,salary
from s_emp where  rownum<8;
顯示第二頁數據   [8,15)
select  rownum,first_name,salary
from s_emp where  rownum<15 and
rownum>7;

select * from (select  rownum r,
first_name,salary
from s_emp where  rownum<15)where r>7;

按照工資排序  每頁顯示7 條
顯示第二頁數據

select   first_name,salary from s_emp
    order by salary;
先編號  還是 先排序?先排序
select* from(
    select rownum r,first_name,salary
    from(select  first_name,salary
        from s_emp order by salary)
    where rownum<2*7+1
 )where r>(2-1)*7;

---------------------------------------
列出sql中 和 NULL 相關的知識點?

發佈了72 篇原創文章 · 獲贊 6 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章