描述一個表用 desc employees
過濾重復的部門 select distinct department_id from employees
別名的三種方式: 1、空格 2、加as 3、" "(多個單詞組成的別名必須加空格,要麼用下劃線分開)
條件匹配日期的: where to_char(date,'yyyy-mm-dd')='1997-06-07'
默認格式: where date = '7-6月-1997'
like: where name like '%\_%' escape '\' (%:0個或者多個字符,_表示任意一個字符,escape表示轉義關鍵字)
order by salary asc(升序) desc(降序)
多層排序: order by salary asc,name asc (在工資相同的情況下按照名字升序排列)
刪除表中字段重復的記錄:
delete from job_grades j1
where rowid <> (select min(rowid) from job_grades j2 where j1.grade_level = j2.grade_level);
如果刪除表中自然順序的第15行,下面語句可實現。
(rowid是數據庫的一個偽列,建立表的時候數據庫會自動為每個表建立ROWID列
用來唯一標識一行記錄。rowid是存儲每條記錄的實際物理地址,對記錄的訪問是基於ROWID。)
delete from tab where rowid=(
select ii from (select ROWNUM nn,ROWID ii from tab WHERE ROWNUM<=15) WHERE nn=15);
等值連接:
select employee_id,e.department_id,department_name,city
from employees e,departments d,locations l
where e.department_id = d.department_id and d.location_id = l.location_id
或者
select employee_id,e.department_id,department_name,city
from employees e
join departments d on e.department_id = d.department_id
join locations l on d.location_id = l.location_id
等值連接另外方式:
select last_name,department_id,department_name
from employees join departments
--using (department_id) (前提是兩表的列名以及列的數據類型要一樣)
非等值連接
select employee_id,last_name,salary,grade_level
from employees e,job_grades j
where e.salary between j.lowest_sal and j.highest_sal
左外連接(哪邊空就把“+”號放在哪個表上)
select e.employee_id,e.last_name,d.department_name
from employees e,departments d
where e.department_id = d.department_id(+)
左外(右外、滿)連接
select employee_id,e.department_id,department_name
from employees e
left outer
--right outer
--full
join departments d on e.department_id = d.department_id
自連接
--查詢公司中員工‘Chen’的manager的信息。
select e1.last_name,e2.last_name,e2.email,e2.salary
from employees e1,employees e2
where e1.manager_id = e2.employee_id and lower(e1.last_name) = 'chen'
組函數:(注意:只要不是組函數中的列都應該放在group by中,group by中的順序不做限定,且其中有的列select中可以沒有)
select department_id,job_id,avg(salary)
from employees
group by department_id,job_id
order by department_id asc
有組函數的過濾條件用having而不能用where:
select department_id,avg(salary)
from employees
having avg(salary)>6000
group by department_id
order by department_id asc
查詢全公司獎金基數的平均值(注意:avg、count默認是不把值為null的計入,此時要想計入的話必須使用nvl()函數):
select avg(nvl(commission_pct,0))
from employees
查詢公司在1995-1998年之間,每年雇傭的人數:
select count(*) "total",
count(decode(to_char(hire_date,'YYYY'),'1995',1,null)) "1995",
count(decode(to_char(hire_date,'YYYY'),'1996',1,null)) "1996",
count(decode(to_char(hire_date,'YYYY'),'1997',1,null)) "1997",
count(decode(to_char(hire_date,'YYYY'),'1998',1,null)) "1998"
from employees
where to_char(hire_date,'YYYY') in ('1995','1996','1997','1998')
單行子查詢:
誰的工資比‘Abel’的高
select last_name,salary
from employees
where salary > (select salary from employees where last_name = 'Abel')
查詢員工為Chen的manager的信息
方法一:(使用自連接)
select e2.last_name,e2.manager_id,e2.email,e2.salary
from employees e1,employees e2
where e1.manager_id = e2.employee_id and e1.last_name = 'Chen'
方法二:
select employee_id,last_name,email,salary
from employees
where employee_id = (
select manager_id
from employees
where last_name = 'Chen')
返回job_id與141號員工相同,salary比143號員工多的員工姓名、job_id和工資
select employee_id,last_name,email,salary
from employees
where employee_id = (
select manager_id
from employees
where last_name = 'Chen')
返回公司工資最少的員工的last_name,job_id,salary
select last_name,job_id,salary
from employees
where salary = (select min(salary) from employees)
查詢最低工資大於50號部門最低工資的部門id和其最低工資
select department_id,min(salary)
from employees
group by department_id
having min(salary)>(select min(salary) from employees where department_id = 50)
多行子查詢(in,any,all):
返回其它部門中比job_id為‘IT_PROG’部門任一工資低的員工的員工號、姓名、job_id以及salary
select employee_id,last_name,job_id,salary
from employees
where job_id <>'IT_PROG' and salary < any (select salary from employees where job_id = 'IT_PROG')
order by last_name asc
返回其它部門中比job_id為‘IT_PROG’部門所有(任意)工資低的員工的員工號、姓名、job_id以及salary
select employee_id,last_name,job_id,salary
from employees
where job_id <>'IT_PROG' and salary < any (select salary from employees where job_id = 'IT_PROG')
order by last_name asc
查詢平均工資最低的部門信息
select *
from departments
where department_id = (select department_id
from employees
having avg(salary) = (select min(avg(salary))from employees
group by department_id)
group by department_id)
查詢平均工資最低的部門信息和該部門的平均工資
select d.* ,(select avg(salary) from employees where department_id = d.department_id)
from departments d
where department_id = (select department_id
from employees
having avg(salary) = (select min(avg(salary))from employees
group by department_id)
group by department_id)
查詢平均工資最高的job信息
select *
from jobs
where job_id in (select job_id
from employees
having avg(salary) = (select max(avg(salary))from employees group by job_id)
group by job_id)
查詢平均工資高於公司的部門有哪些
select department_id,avg(salary)
from employees
group by department_id
having avg(salary)>(select avg(salary) from employees)
查詢公司中所有manager的詳細信息
select *
from employees
where employee_id in (select manager_id from employees)
各個部門中,最高工資中最低的那個部門的 最低工資是多少
select min(salary)
from employees
where department_id = (select department_id
from employees
having max(salary)=(select min(max(salary))
from employees
group by department_id)
group by department_id
)
查詢平均工資最高的的部門的manager的詳細信息:last_name,department_id,email,salary
select last_name,department_id,email,salary
from employees
where employee_id in (select manager_id
from employees
where department_id = (select department_id
from employees
having avg(salary) = (select max(avg(salary))
from employees
group by department_id)
group by department_id))
查詢1999年來公司的員工中的最高工資的那個員工的信息
select *
from employees
where salary = (select max(salary)
from employees
where employee_id in (select employee_id
from employees
where to_char(hire_date,'YYYY') = '1999'))
and to_char(hire_date,'YYYY') = '1999'
查看用戶定義的表:
select table_name from user_tables;
查詢數據庫有哪些對象(表、視圖、序列、同義詞)
select * from user_catalog;
查看用戶定義的各種數據庫對象
select distinct object_type from user_objects;
創建表的第一種方式:(白手起家)
create table emp1(
id number(10),
name varchar2(20),
salary number(10,2),
hire_date date
)
第二種方式:借助現有的表來創建(數據也會在原有的表中搬過來)
create table emp2
as select employee_id id,last_name name,hire_date,salary
from employees
(where department_id = 80)
(where department_id = 800):不想要任何數據就給它寫個沒有的部門或者:where 1=2
修改表:
給表追加多一列:
alter table emp1
add (email varchar2(20))
修改表中的列屬性:
1、alter table emp1
modify (id number(15))
2、alter table emp1
modify (salary number(20,2) default 2000)
刪除一個列:
alter table emp1
drop column email
重命名列:
alter table emp1
rename column salary to sal
刪除表:
drop table emp5
清空表:
truncate table emp3;(不可以回滾)
delete from emp2;(可以回滾)
重命名表:
rename emp2 to employees2;
表數據的增、刪、改:
向表中增加數據
1、insert into emp1 ‘sysdate’或者
values (1002,'BB',to_date('1998-08-08','yyyy-mm-dd'),20000)
2、insert into emp1
values (1002,'BB',to_date('1998-08-08','yyyy-mm-dd'),null)
3、insert into emp1(employee_id,last_name,hire_date) 注意:這裡是只給部分列賦值,有非空約束的必須賦值
values (1004,'DD',to_date('1990-08-08','yyyy-mm-dd'))
4、注意:只想賦值一部分列的話,其它必須是允許放空值的列,這裡默認salary是NULL(即有非空約束的必須賦值)
insert into emp1(employee_id,last_name,hire_date)
values (1005,'EE',to_date('1996-08-08','yyyy-mm-dd'))
5、彈窗式的插入數據
insert into emp1(employee_id,last_name,hire_date,salary)
values (&id,'&last_name','&hire_date',&salary)
基於現有表的記錄插入數據
insert into emp1(employee_id,last_name,hire_date,salary)
select employee_id,last_name,hire_date,salary
from employees
where department_id = 80
更新數據:
update emp1
set salary = 22000
where employee_id = 179
更新114員工的工作和工資使其與206號員工相同
1、select employee_id,job_id,salary
from employees1
where employee_id in (114,205)
2、update employees1
set job_id = (
select job_id from employees1 where employee_id = 205
),salary = (
select salary from employees1 where employee_id = 205
)
where employee_id = 114
調整與employee_id為200的員工的job_id相同的
員工的department_id為employee_id為100的員工的department_id
update employees1
set department_id = (select department_id from employees1 where employee_id = 100)
where job_id = (select job_id from employees1 where employee_id = 200)
容易出現的數據完整性的錯誤如:
update employees
set department_id = 55
where department_id = 100; 問題出現在表中55號部門本來就不存在
從employees表中刪除departments部門名稱中含有Public字符的部門id
delete from employees1
where department_id = (select department_id from departments where department_name like '%Public%')
增:
insert into ...
values(...)
insert into ...
select...from...where...
改:
update ...
set ...
where ...
刪:
delete from ...
where ...
事務:
commit;
savepoint A;
rollback to savepoint A;
當用戶操作表的時候,還沒有commit之前,其它用戶是不能夠對當前的表進行操作的
更改108號員工的信息:使其工資變為所在部門中的最高工資,job變為公司中平均工資最低的 job
update employees
set salary = (select max(salary)
from employees
where department_id = (
select department_id
from employees
where employee_id = 108)
group by department_id),
job_id = (select job_id
from employees
having avg(salary) = (
select min(avg(salary))
from employees
group by job_id )
group by job_id)
where employee_id = 108
刪除108號員工所在部門中工資最低的那個員工
delete from employees
where employee_id = (
select employee_id
from employees
where department_id = (select department_id
from employees
where employee_id = 108)
and salary = (select min(salary)
from employees
where department_id =(select department_id
from employees
where employee_id = 108)
)
)
可以優化成:
delete from employees e
where department_id = (select department_id
from employees
where employee_id = 108)
and salary = (select min(salary)
from employees
where department_id = e.department_id
)
使用約束not null和unique創建表:其中在有unique約束中給它賦值多個null,null之間是不沖突的
create table emp3(
--列級約束:
id number(10) constraint emp3_id_uk unique,
name varchar2(20) constraint emp3_name_nn not null,
email varchar2(20),
salary number(10),
--表級約束:
constraint emp3_email_uk unique(email)
)
主鍵約束:能夠唯一的確定一條記錄,同樣也分表級約束和列級約束,primary key不僅是not null而且unique
create table emp4(
id number(10) constraint emp4_id_pk primary key,
name varchar2(20) constraint emp4_name_nn not null,
email varchar2(20),
salary number(10),
constraint emp4_email_uk unique(email)
)
或者
create table emp4(
id number(10),
name varchar2(20) constraint emp4_name_nn not null,
email varchar2(20),
salary number(10),
constraint emp4_email_uk unique(email),
constraint emp4_id_pk primary key(id)
)
外鍵約束:(注意:在emp6中插入數據的時候,不能夠插入departments表中department_id沒有的數據記錄。另外,外鍵引用的列起碼要有一個唯一的約束)
create table emp6(
id number(10),
name varchar2(20) constraint emp6_name_nn not null,
email varchar2(20),
salary number(10),
department_id number(10),
constraint emp6_email_uk unique (email),
constraint emp6_id_pk primary key(id),
constraint emp6_dept_id_fk foreign key(department_id) references departments(department_id)
)
向表中插入departments表中存在的department_id(主鍵)數據
insert into emp6
values(1002,'AA',null,10000,20)
on delete set null:(級聯置空:子表中相應的列置空)
on delete cascade:(級聯刪除:當父表中的列被刪除時,子表中相對應的列也被刪除)
create table emp7(
id number(10),
name varchar2(20) constraint emp7_name_nn not null,
email varchar2(20),
salary number(10),
department_id number(10),
constraint emp7_email_uk unique (email),
constraint emp7_id_pk primary key(id),
constraint emp7_dept_id_fk foreign key(department_id) references departments(department_id) on delete set null
)
check約束:比如約束工資的范圍
create table emp8(
id number(10),
name varchar2(20) constraint emp8_name_nn not null,
email varchar2(20),
salary number(10) constraint emp8_salary check(salary>1500 and salary<30000),
department_id number(10),
constraint emp8_email_uk unique (email),
constraint emp8_id_pk primary key(id),
constraint emp8_dept_id_fk foreign key(department_id) references departments(department_id) on delete set null
)
修改約束:
添加not null約束
alter table emp5
modify (salary number(10,2) not null)
刪除約束:
alter table emp5
drop constraint emp5_name_nn
添加unique約束
alter table emp5
add constraint emp5_name_uk unique(name)
無效化約束:
alter table emp3
disable constraint emp3_email_uk
激活約束:
alter table emp3
enable constraint emp3_email_uk
查詢約束:(注意:其中條件裡的表名要大寫)
select constraint_name,constraint_type,search_condition
from user_constraints
where table_name = 'EMPLOYEES'
查詢定義有約束的列有哪些:
select constraint_name,column_name
from user_cons_columns
where table_name = 'EMPLOYEES'
視圖:
它實際上是一個虛表,它是依賴於基表的,當視圖中的數據更改時,基表中的相應數據也被更改
為什麼要使用視圖?
答:1、可以控制數據訪問 2、簡化查詢 3、避免重復訪問相同的數據
創建視圖:
create view empview
as
select employee_id,last_name,salary
from employees
where department_id = 80
基於多張表來創建視圖:
create view empview3
as
select employee_id id,last_name name,salary,e.department_name
from employees e,departments d
where e.department_id = d.department_id
修改視圖:create or replace
create or replace view empview2
as
select employee_id id,last_name name,department_name
from employees e,departments d
where e.department_id = d.department_id
屏蔽DML操作:with read only (其他用戶只能查看,不能增、刪、改)
create or replace view empview2
as
select employee_id id,last_name name,department_name
from employees e,departments d
where e.department_id = d.department_id
with read only
簡單視圖和復雜視圖的區別:簡單視圖沒有分組函數,在復雜視圖中若使用了組函數創建的,則對它不能使用DML(增、刪、改)的操作,因為有些列在基表中原本是不存在的。
創建一個復雜視圖:(注意:基表中不存在的列,創建視圖時要給它個別名,如下面的平均工資。)
create or replace view empview3
as
select department_name dept_name,avg(salary) avg_sal
from employees e ,departments d
where e.department_id = d.department_id
group by department_name
rownum是一個偽列,跟id有點相關,且有它自己的一個排序。
比如,你想找到表中工資最高的前10位的員工,以下用rownum作為條件是不行的,因為它有自己默認的排列順序
select rownum,employee_id,last_name,salary
from employees
where rownum <= 10
order by salary desc
要真想用rownum達到查詢最高工資的前10位則要如下這樣:(注意:rownum只能使用<或<=,而用=,>,>=都不會返回任何數據)
select rownum,employee_id,last_name,salary
from (select employee_id,last_name,salary
from employees
order by salary desc)
where rownum <=10
那麼要查詢最高工資排列40-50名的數據要怎麼辦?如下:(此時最外層的rn已經不是偽列了)
select rn,employee_id,last_name,salary
from (select rownum rn,employee_id,last_name,salary
from (select employee_id,last_name,salary
from employees
order by salary desc))
where rn <40 and rn<=50
序列:主要用來提供主鍵值
創建序列:
create sequence empseq
increment by 10
start with 10
maxvalue 100
cycle
nocache
序列在數據插入表時在主鍵位置的作用:
先:
create table emp01
as
select employee_id,last_name,salary
from employees
where 1=2
然後:
insert into emp01
values(empseq.nextval,'BB',3300)
修改序列:(能修改增量、最大值、最小值、是否循環以及是否裝入內存,如要更改初始值則要通過刪除序列重新創建序列,因為改後可能會與之前的數據發生沖突,因為序列是唯一的)
alter sequence empseq
increment by 1
nocycle
序列一以下情況中會出現裂縫:
1、回滾
2、系統出現異常
3、多個表同時使用同一個序列
查詢序列:(如果指定了nocache選項,則last_number返回的是序列中下一個有效值)
select sequence_name,min_value,max_value,increment_by,last_number
from user_sequences
刪除序列
drop sequence empseq
索引的作用,能夠加速 oracle服務器的查詢速度,主鍵和唯一約束中系統默認為它所約束的列創建所引,也可以為非唯一的列手動創建所引,創建好之後系統會自動調用索引,不用你手動編碼調用
創建索引:
create index emp01_id_ix
on emp01(employee_id)
刪除索引:
drop index emp01_id_ix
什麼時候創建索引?
1、列中數據值分布范圍很廣
2、列經常在where子句或者連接條件中出現
3、表經常被訪問而且數據量很大,訪問的數據大概占數據總量的2%到4%
什麼時候不要創建索引?
1、表很小
2、表經常更新
3、查詢的數據大於2%到4%
4、表不經常作為where子句或者連接條件中出現
同義詞:
創建同義詞
create synonym e for employees
刪除同義詞
drop synonym e
創建用戶和密碼:
create user atguigu01
identified atguigu01;
給用戶登錄數據庫的權限,(create table,create sequence,create view,create procedure)
grant create session
to atguigu01 ;
創建用戶表空間
alter user atguigu01 quota unlimited(或者5M)
on users
更改用戶自己的密碼:
alter user atguigu01
identified by atguigu;
角色:使用角色分配給用戶權限會更快,角色有什麼權限,用戶就有什麼權限
1、創建角色
create role my_role
2、為角色賦予權限
grant create session,create table,create view
to my_role
3、將角色賦予用戶
grant my_role to atguigu02
對象:
1、給atguigu01分配表employees的查詢、修改的權限
grant select,update
on scott.employees
to atguigu01
驗證上一步的操作:
update scott.employees
set last_name = 'ABCD'
where employee_id = 206 (此時改的是scott用戶中的表,atguigu只是調用它的表,並沒有復制過來)
(未完,待續......)
Oracle有很多值得學習的地方,Oracle體系太龐大了,對於初學者來說,難免會有些無從下手的感覺,什麼都想學,結果什麼都學不好,所以把學習經驗共享一下,希望讓剛剛入門的人對Oracle有一個總體的認識,少走一些彎路。 一、定位 Oracle分兩大塊,一塊是開發,一塊是管理。開發主要是寫寫存儲過程、觸發器什麼的,還有就是用Oracle的Develop工具做form。有點類似於程序員,需要有較強的邏輯思維和創造能力,個人覺得會比較辛苦,是青春飯;管理則需要對Oracle數據庫的原理有深刻的認識,有全局操縱的能力和緊密的思維,責任較大,因為一個小的失誤就會down掉整個數據庫,相對前者來說,後者更看重經驗。 因為數據庫管理的責任重大,很少公司願意請一個剛剛接觸Oracle的人去管理數據庫。對於剛剛畢業的年輕人來說,可以先選擇做開發,有一定經驗後轉型,去做數據庫的管理。當然,這個還是要看人個的實際情況來定。 二、學習方法 我的方法很簡單,就是:看書、思考、寫筆記、做實驗、再思考、再寫筆記。 看完理論的東西,自己靜下心來想想,多問自己幾個為什麼,然後把所學和所想的知識點做個筆記;在想不通或有疑問的時候,就做做實驗,想想怎麼會這樣,同樣的,把實驗的結果記下來。思考和做實驗是為了深入的了解這個知識點。而做筆記的過程,也是理清自己思路的過程。 Oracle學習過程是使一個問題由模糊到清晰,再由清晰到模糊的過程。而每次的改變都代表著你又學到了一個新的知識點。 Oracle學習過程也是從點到線,從線到網,從網到面的過程。當點變成線的時候,你會有總豁然開朗的感覺。當網到面的時候,你就是高手了。 很多網友,特別是初學的人,一碰到問題就拿到論壇上來問,在問前,你有沒有查過書,自己有沒有研究過,有沒有搜索一下論壇?這就叫思維惰性。由別人來回答你的問題,會讓你在短時間內不費勁地弄懂這個知識點,然而通過自己的努力去研究它,不但會更深入的了解這個知識點,更重要的是在研究的過程會提高你解決問題和分析問題的能力。總的來說,沒有鑽研的學習態度,不管學什麼東西,都不會成功的。 當然,初學的人很多時候是因為遇到問題時,無從下手,也不知道去哪裡找資料,才會到論壇上提問題的。但我認為,在提問的時候,是不是可以問別人是如何分析這個問題?從哪裡可以找到相關的資料?而不是這個問題的答案是什麼?授人以魚不如授人以漁。
Oracle.9i&10g編程藝術深入數據庫體系
Oracle.DBA手記_數據庫診斷案例與性能優化實踐
深入解析Oracle.DBA入門進階與診斷案例
Oracle_Press_Oracle_Database_10g_Performance_Tuning_Tips_and_Techniques
強力推薦最後一本