/*
達內學習 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 相關的知識點?