1. 程式人生 > 其它 >ORACLE資料庫之SQL語言基礎

ORACLE資料庫之SQL語言基礎

1、SQL語言基礎

SQL是Structured Query Language(結構化查詢語言)的簡稱,是使用者與資料庫交流所需要的標準語言。

1.1 SQL語言簡介

1.1.1 SQL語言特點

1)綜合統一
2)集合性
3)統一性
4)高度非過程化
5)語言簡單
6)以同一種語言結構提供兩種使用方式(互動式應答使用、預編譯SQL進行執行)
7)是所有關係資料庫的公共語言。

1.1.2 SQL語言分類

1)資料定義(DDL):create、drop、alter
2)資料操縱(DML):select、insert、update、delete
3)資料控制(DCL):grant、revoke

1.1.3 SQL語言編寫規則

1)SQL關鍵字不區分大小寫
2)物件名和列名不區分大小寫
3)字元值區分大小寫
4)在SQL*Plus環境編寫SQL語言時,如果SQL語言較短,則可以將語言放在一行上顯示;
如果SQL語言很長,為了便於使用者閱讀,則可以將語言分開顯示(並且Oracle會在除第一行外的每一行前面自動加上行號),當SQL輸入完畢,要以分號作為結束符。

2、使用者模式

某個使用者所建立的資料庫物件就都屬於該使用者模式。

2.1 模式與模式物件

模式是一個數據庫物件的集合。模式為一個數據庫物件所有,並且具有與該使用者相同的名稱。如SCOTT模式。
在一個模式內部不可以直接訪問其他模式的資料庫物件,即使具有訪問許可權情況下也需要指定模式名稱才可以訪問其他模式的資料庫物件。
模式物件是由使用者建立的邏輯結構,用於儲存或者引用資料。如表、索引等。
模式與模式物件之間是擁有和被擁有的關係,即模式擁有模式物件,而模式物件被模式擁有。
示例:SCOTT模式下所擁有的模式物件

#通過檢索user_tables表來顯示SCOTT模式所擁有的4個數據表
connect scott
select table_name from user_tables
#在system模式下,通過檢索dba_tables表來顯示SCOTT模式所擁有的4個數據表
connect system
select table_name from bda_tables where owner='SCOTT'

3、檢索資料

檢索資料可以通過select語句來實現。該語句基本語法如下:

select {[distinct|all] columns|*}
[into table_name]
from {tables|views|other select}
[where conditions] 
[group by columns] 
[having conditions] 
[order by columns] 

select子句:用於選擇資料表、檢視中的列。
into子句:用於將原表的結構和數插到新表中。
from子句:用於指定資料來源,包括表、檢視和其他select語句。
where子句:用於對檢索的資料進行篩選。
group by子句:用於對檢索的結果進行分組顯示。
having子句:用於從使用group by子句分組後的查詢結果中篩選資料行。
order by子句:用於對結果集進行排序(包含升序和降序)。

3.1 簡單查詢

只包含select子句和from子句的查詢就是簡單查詢。
1)檢索所有的列

select * from dept;

2)檢索指定的列
在Oracle資料庫中,有一個標識行中唯一特性的行識別符號,該行識別符號的名稱為ROWID,是隱藏列,也成為偽列,長度為18為字元,包含該行資料在Oracle資料庫中的實體地址。

select job,ename,empno from emp;
select rowid,job,ename from emp;

3)查詢日期列
日期列的預設顯示格式為DD-MON-RR
以簡體中文顯示日期結果

alter session set nls_date_language='SIMPLIFIED CHINESE';
select ename,hiredate from emp;

以美國英語顯示日期結果

alter session set nls_date_language='AMERICAN';
select ename,hiredate from emp;

以特定格式顯示日期結果

alter session set nls_date_format='YYYY"年"MM"月"DD"日"';
select ename,hiredate from emp;

使用TO_CHAR函式定製日期顯示函式,將日期轉變為特定格式的字串。

4)帶有表示式的SELECT子句

select sal*(1+0.1) from emp;

5)為列指定別名
為了方便檢視檢索結果,為列指定別名。
為列起別名,AS關鍵字為可選項,使用者可以在列名稱的後面直接指定列別名。

select empno as "員工編號",ename as "員工姓名",job as "職務" from emp;
select empno "員工編號",ename "員工姓名",job "職務" from emp;

6)顯示不重複記錄

select distinct job from emp;

7)處理NULL值
使用函式NVL處理空值。

select ename,sal,comm,sal+nvl(comm,0) job from emp;

當使用nvl(comm,0)處理空值時,如果comm存在數值,則函式返回原有數值;如果comm不存在數值,則函式返回0.
8)連線字串
使用“||”操作符連線字串

select ename,||""||'s job is '||job from emp;

使用函式CONCAT連線字串

select concat(concat(ename,'''s job is '),job) from emp;

3.2 篩選查詢

語法格式

select columns_list
from table_name
where conditional_expression

1)比較篩選
比較篩選的操作主要有以下6種情況:
A=B、A<>B、A>B、A<B、A>=B、A<=B

select empno,ename,sal
from emp
where sal>1500;

兩種特殊的“比較篩選”操作:
A{operator}ANY(B):表示A與B中的任何一個元素進行operator運算子的比較,只要有一個比較值為true,就返回資料行。
A{operator}ALL(B):表示A與B中的所有一個元素進行operator運算子的比較,只要所有元素比較值為true,才返回資料行。

select empno,ename,sal
from emp
where sal<>all(1500,950,800);

2)使用特殊關鍵字篩選
like關鍵字:需要使用萬用字元在字串內查詢指定的模式。
%萬用字元代表0個或者多個字元。
_萬用字元代表一個且只能是一個字元。

select empno,ename,job
from emp
where ename like 'S%'; #S開頭的任意字串

要查詢字串中含有“%”或“_”時,可以使用轉義關鍵字(\)實現查詢。

in關鍵字:表示查詢指定的值在某一目標值中。not in表示查詢指定的值不在某一目標值中。

select empno,ename,job
from emp
where job in ('PRESIDENT','MANAGER','ANALUST'); 

BETWEEN關鍵字:需要返回某一個數據值是否位於兩個給定的值之間。通常使用BETWEEN...AND和NOT...BETWEEN...AND來指定範圍條件。

select empno,ename,sal
from emp
where sal between 2000 and 3000;

IS NULL關鍵字:
空值

select ename,mgr
from emp
where mgr is null;

3)邏輯篩選
在WHERE子句中使用邏輯運算子AND、OR和NOT進行資料篩選的操作。
AND邏輯運算子:邏輯與
OR邏輯運算子:邏輯或
NOT邏輯運算子:邏輯非

3.3 分組查詢

select columns_list
from table_name
[where conditional_expression] 
group by columns_list

1)使用GROUP BY子句進行單列分組
單列分組是基於列生成分組統計結果。當基於分組列的每個不同值生成一個統計結果。
GROUP BY子句經常和聚集函式一起使用,可以實現對查詢結果中每一組資料進行分類統計。
AVG:平均值
COUNT:計數
MAX:最大值
MIN:最小值
SUM:求和

select job,avg(sal),sum(sal),max(sal),count(job)
from emp
group by job

在使用GROUP BY子句時候應該注意:
在SELECT子句後面只可以有兩種表示式:統計函式和進行分組的列名。
SELECT子句中的列名必須是進行分組的列,除此之外其他全部是錯誤的,但是GROUP BY子句
後面的列名可以不出現在SELECT子句中。
預設情況,按照GROUP BY子句指定的分組列升序排列,如需重新排序可使用ORDER BY子句指定新的排序順序。

select avg(sal)
from emp
group by job

2)使用GROUP BY子句進行多列分組
多列分組是指基於兩個或兩個以上的列生成分組統計結果。

select deptno,job,avg(sal),max(sal)
from emp
group by deptno,job;

3)使用ORDER BY子句改變分組排序結果
使用GROUP BY子句執行分組統計時候,會自動基於分組列進行升序排列。
為了改變分組列的排序結果,需要使用ORDER BY子句指定新的排序順序。

select deptno,sum(sal)
from emp
group by deptno
order by sum(sal) desc;

4)用HAVING子句限制分組結果
HAVING子句通常與GROUP BY子句一起使用,在完成對分組結果統計後,使用HAVING子句對分組的結果做進一步的篩選。
如果不使用GROUP BY子句,HAVING子句和WHERE子句的功能一樣。
HAVING子句和WHERE子句相似之處都可以定義搜尋條件,不同之處在於HAVING子句可以包含聚集函式,WHERE子句不可以。

select deptno as 部門編號,avg(sal) as 平均工資
from emp
group by deptno
having avg(sal) >2000;

5)在GROUP BY 子句中使用ROLLUP和CUBE操作符
當直接使用GROUP BY子句進行多列分組時,只能生成簡單的資料統計結果。為了生成資料統計、橫向小計和總計統計,可以在GROUP BY子句中使用ROLLUP操作符。

select deptno as 部門編號,job as 崗位,avg(sal) as 平均工資
from emp
group by rollup(deptno,job);

為了生成資料統計、橫向小計、縱向小計和總計統計,可以使用CUBE操作符。

select deptno as 部門編號,job as 崗位,avg(sal) as 平均工資
from emp
group by cube(deptno,job);

為確定統計結果是否用到特定列,可使用GROUPING函式,如果函式返回0表示統計結果使用了該列;如果返回1表示統計結果未使用到該列。

select deptno,job,sum(sal),grouping(deptno),grouping(job)
from emp
group by rollup(deptno,job);

6)使用GROUPING SETS操作符
GROUPING SETS操作符可以合併多個分組統計結果,簡化多個分組操作。

select deptno,job,avg(sal)
from emp
group by grouping sets(deptno,job);

3.4 排序查詢

select columns_list
from table_name
[where conditional_expression] 
[group by columns_list] 
order by {order_by_expression [ASC|DESC]}

1)單列排序

select deptno,empno,ename from emp order by deptno,empno;

2)多列排序
首先按照第一列進行排序,當第一列存在相同資料時,再以第二列進行排序,以此類推。

select ename,depno from emp order by deptno,sal desc;

3.5 多表關聯查詢

1)表別名
表別名一經定義,在整個查詢語句中就只能使用表的別名而不能使用表名。
2)內連線
內連線就是使用JOIN指定用於連線的兩個表,使用ON指定連線表的連線條件。若進一步限定查詢範圍,則可以直接在後面新增WHERE子句。
內連線返回的查詢結果中只包含符合查詢條件和連線條件的行。

select columns_list 
from table_name1 [inner] JOIN table_name2
ON join_condition

3)外連線
外連線擴充套件了內連線的結果集,除了返回所有的匹配行之外,還返回一部分或者全部不匹配的行。三種外連接種類:
左外連線:不僅包含滿足連線條件的資料行,還包含左表中不滿足連線條件的行。LEFT [OUTER] JOIN
右外連線:不僅包含滿足連線條件的資料行,還包含右表中不滿足連線條件的行。RIGHT [OUTER] JOIN
完全外連線:執行一個完整的左外連線和右外連線查詢,合併、去重。FULL [OUTER] JOIN
4)自然連線
自然連線是指在檢索多個表時,將第一個表中的列與第二個表中具有相同名稱的列進行自動連線,不需要明確指定進行連線的列。NATURAL JOIN關鍵字。
5)自連線
在同一張表之間的連線查詢。
6)交叉連線
實際上不需要任何連線條件的連線。結果是一個笛卡爾積。

select colums_list
from table_name1 cross join table_name2;

4、ORACLE常用系統函式

4.1字元類函式

1)ASCII(c)函式和CHR(i)函式
ASCII(c):用於返回一個字元c的ASCII碼。
CHR(i):用於返回ASCII碼值對應的字元。
dual是Oracle系統內部提供的一個用於實現臨時資料計算的特殊表。它只有一個列DUMMY,型別為VARCHAR2(1).

select ascii('Z') Z,ascii('H') H,ascii('D') D,ascii(' ') space
from dual;

select chr(90),chr(72),chr(68),32 S 
from dual;

2)CONCAT(s1,s2)函式
將字串s2連線到字串s1的後面。

select concat('Hello ','World!') information from dual

3)INITCAP(s)函式
把字串s的每個單詞的第一個字母大寫,其他字母小寫。

select initcap('oh my god!') information from dual

4)INSTR(s1,s2[,i][,j])函式
字串s2在字串s1中第j次出現時的位置,搜尋從字串s1的第i個字元開始。
沒有發現要找的字元,返回0。
i為負數,搜尋從右向左進行,但是函式返回位置還是按照從左到右計算。

select instr('oracle 11g','1',3,2) abc from dual

5)LENGTH(s)函式
返回字串s的長度
6)LOWER(s)函式和UPPER(s)函式
LOWER(s)函式和UPPER(s)函式分別用於返回字串s的小寫形式和大寫形式。
7)LTRIM(s1,s2)函式、RTRIM(s1,s2)函式和TRIM(s1,s2)函式
LTRIM(s1,s2)函式:刪除字串s1左邊的字串s2
RTRIM(s1,s2)函式:刪除字串s1右面邊的字串s2
TRIM(s1,s2)函式:刪除字串s1左右兩端的字串s2
如果不指定字串s2表示去除相應方位的空格。
7)REPLACE(s1,s2[,s3])函式
用s3字串替換出現在s1字串中的所有s2字串,並返回替換後的新字串。s3預設值是空字串。
8)SUBSTR(s,i[,j])函式
從字串s的第i個位置開始擷取長度為j的子字串。如果省略j,則直接擷取到尾部。

4.2數字類函式

ABS(n):絕對值。
CEIL(n):返回大於或等於資料n的最小整數。
FLORR(n):返回小於或等於資料n的最大整數。
SIN(n):正弦,n為弧度。
COS(n):餘弦,n為弧度。
EXP(n):e的n次冪。
SORT(n):返回n的平方根,n為弧度。
LOG(n1,n2):返回以n1為底n2的對數。
MOD(n1,n2):返回n1除以n2的餘數。
POWER(n1,n2):返回n1的n2次方。
ROUND(n1,n2):返回舍入小數點右邊n2位的n1的值,n2的預設值為0.若n2為負數就舍入小數點左邊的位。
SIGN(n):若n為負數,返回-1;若n為正數,返回1。若n為0,返回0.
TRUN(n1,n2):返回結尾到n2位小數的n1值,n2預設為0.n2為預設值,會將n1截尾成整數,若n2為負數就截尾在小數點左邊相應的位上。

4.3日期和時間函式

SYSDATE()函式:返回當前系統時間。
ADD_MONTHS(d,i):返回日期d加上i月之後的結果。

4.4轉換類函式

TO_CHAR(x[,format]):實現將表示式轉換為字串,format表示字串格式。
TO_DATE(s[,format[lan]]):實現將字串s轉換為date型別,format表示字串格式,lan表示所使用的語言。
TO_NUMBER(s[,format[lan]]):返回字串s代表的數字,返回值按照format格式進行顯示,format表示字串格式,lan表示所使用的語言。

select sysdate as 預設格式日期,to_char(sysdate,'YYYY-MM-DD') as 轉換後日期
from dual

4.5聚合類函式

AVG():平均值
COUNT():計數
MAX():最大值
MIN():最小值
SUM():求和
VARIANCE():統計方差
STDDEV():標準偏差

5、子查詢的用法

子查詢是在SQL語句內的另外一條select語句。

select empno,ename,job from emp
where deptno=(select deptno from dept
where dname='RESEARCH');

子查詢規則:
1)必須用括號‘()’括起來。
2)子查詢中不能包含ORDER BY子句。
3)子程式允許巢狀多層,但是不能超過255層。

5.1單行子查詢

單行子查詢是指返回一行資料的子查詢語句。在WHERE子句中引用單行子查詢時,可以使用單行比較運算子(=、>、<、>=、<=和<>)。

select empno,ename,sal from emp
where sal>(select min(sal) from emp)
and sal<(select max(sal) from emp)

5.2多行子查詢

多行子查詢是指返回多行資料的子查詢語句。在WHERE子句中引用多行子查詢時,必須使用多行比較運算子(IN、ANY、ALL)。
1)使用IN運算子
當子多行子查詢中使用IN運算子時,外查詢會嘗試與子查詢結果中的任何一個結果進行匹配,只要有一個匹配成功,則外查詢返回當前檢索的記錄。

select empno,ename,job 
from emp
where deptno in 
(select deptno  from dept where dname<>'SALES');

2)使用ANY運算子
ANY運算子必須與單行操作符結合使用,並且返回行只要匹配子查詢的任何一個結果即可。

select deptno,ename,sal from emp
where sal>any(select sal from emp where depno=10) and deptno<>10;

3)使用ALL運算子
ALL運算子必須與單行操作符結合使用,並且返回行必須匹配子查詢的所有子查詢結果。

select deptno,ename,sal from emp
where sal>all(select sal from emp where depno=30);

5.3關聯子查詢

單行子查詢和多行子查詢中,內查詢和外查詢是分開執行的,也就是說內查詢與外查詢的的執行是沒有關係的,外查詢僅僅是使用內查詢的最終結果。
一些特殊的需求,內查詢的執行需要藉助於外查詢,而外查詢的執行又離不開內查詢的執行,這時,內查詢和外查詢是相互關聯的,這種子查詢就被稱為關聯子查詢。

--在emp表中,使用‘關聯子查詢’檢索工資大於同職位平均工資的員工資訊
select empno,ename,sal
from emp f
where sal>(select avg(sal) from job=f.job)
order by job;

關聯子查詢不僅可以作為SELECT語句的子查詢,也可以作為INSERT、UPDATE或DELETE語句的關聯子查詢。

6、操作資料庫

6.1插入資料(INSERT語句)

INSERT語句注意事項:
當為資料列增加資料,可以直接提供數字值,或者用單引號引住。
當為字元列或日期列增加資料,必須用單引號引住。
當增加資料時,資料必須滿足約束規則,並且必須為主鍵列和NOT NULL列提供資料。
當增加資料時,資料必須與列的個數和順序保持一致。
1)單條插入資料

INSERT INTO table_name[(column_name1[,column_name1]...)]
VALUES(express1[,express2]...)

使用列列表增加資料
既可以是資料表的全部列,也可以是不分列,但是注意不為空的列必須列出來。

insert into dept(deptno,dname,loc)
values(88,'design','beijing');

不使用列列表增加資料
必須根據表中定義的列順序,為所有的列提供資料。
'''
desc jobs;--查詢表結構和列的定義順序。
insert into jobs
values('PRO','程式設計師',5000,10000);
'''
使用特定格式插入日期值
在增加日期資料時,可以使用TO_DATE函式實現日期的轉換。

insert into emp(empno.ename,job,hiredate)
values(1356,'MARY','CLERK',to_date('1983-10-20','YYYY-MM-DD'));

使用DEFAULT提供資料
預設值,如果不存在預設值,自動生成NULL

insert into dept
values(60,'MARKET',DEFAULT);

2)批量插入資料

INSERT INTO table_name[(column_name1[,column_name1]...)] selectSubquery
INSERT INTO job_temps
select * from jobs
where jobs.max_salary>10000

6.2更新資料(UPDATE語句)

更新資料時,更新的列數可以由使用者自己指定,列與列之間用逗號分隔更新的條數可以通過WHERE子句來加以限制。

UPDATE table_name
SET{column_name1=express1[,column_name2=express2...]
|(column_name1[,column_name2...])=(selectSubquery)}
[WHERE condition]

更新資料注意事項:
當更新數字列時,可以直接提供數字值,或者用單引號引住。
當更新字元列或日期列時,必須用單引號引住。
當更新資料時,資料要滿足約束條件。
當更新資料時,資料必須與列的資料型別匹配。
1)更新單列資料

update emp
set sal=2460
where ename='SCOTT'

2)更新多列資料

update emp
set sal=sal*1.2,sal1=sal1*1.2
where job='SALESMAN'

3)更新日期列資料

update emp
set hiredate=TO_DATE('1984/01/01','YYYY/MM/DD')
where empno=7788

4)使用DEFAULT選項更新資料

update emp
set job=DEFAULT
where ename='SCOTT'

5)使用子查詢更新資料

update emp
set sal=(select avg(sal)
from emp where job='MANAGER')
where sal<2000;

6.3刪除資料(DELETE語句和TRUNCATE語句)

1)DELETE語句
可以刪除資料庫中的所有記錄和指定範圍的記錄。如果刪除指定範圍的記錄,要通過WHERE子句進行限制。

DELETE FROM table_name
[WHERE condition]
delete from jobs
where job_id='PRO';

如果不指定WHERE子句,那麼會刪除表的所有資料。

delete from emp;

2)TRUNCATE語句
TRUNCATE語句刪除表中所有記錄。比DELETE語句刪除表中所有資料快很多。因為TRUNCATE語句刪除資料不會產生資料回滾記錄。所以TRUNCATE語句的操作也無法使用ROLLBACK語句撤銷。

truncate table jobs_temp;

需要說明,在TRUNCATE語句中還可以使用REUSE STORAGE關鍵字或DROP STORAGE關鍵字,前者表示刪除記錄後仍然儲存記錄所佔用的空間,後者表示刪除記錄後立即回收記錄佔用的空間。預設情況下TRUNCATE語句使用DROP STORAGE關鍵字。