ORACLE 資料庫的基本操作語句
1.簡單的表操作
建立一個簡單的表
create table student(
name varchar2(20),
age number(3)
);
插入新記錄
insert into student values('Tom', 18);
insert into student values('張三', 20);
insert into student values('李四', 22);
insert into student values('王五', 26);
查詢所有記錄
select * from student;
查看錶結構
desc student;
刪除表
drop table student;
刪除表中所有的資料(保留表結構)
delete from student;
刪除表中指定的資料
delete from student where age=20;
提交
commit;
2.SQL語句分類
DML 語句(資料操作語句)
- Insert(用於新增欄位), Update(用於修改已有欄位),
DDL 語句(資料定義語句)
- Create, Alte(用於新增列)r, Drop, Truncate
DCL 語句(資料控制語言)
- Grant, Revoke
事務控制語句
- Commit, Rollback, Savepoint
Select 查詢語句
簡單的Select語句
* 語法格式
- SELECT *|{<欄位名>, ...}
- FROM <表名>;
使用算術表示式
* 在 Select 語句中,對 NUMBER 型資料可以使用算術運算子建立表示式.
- select empno, ename, sal, sal*12 from emp;
* 算術運算子( + - * / )
* 運算優先順序
- 先乘除後加減
- 同級運算從左到右
- 表示式中可使用小括號強行改變運算順序
- select empno, ename, sal, sal*12+1000 from emp;
- select empno, ename, sal, sal*(12+1000) from emp;
連線運算子
* 連線運算子'||'可以把列與字元,或其它表示式連線在一起,得到一個新的字串,實現'合成'列的功能.
* 用法舉例:
- select empno, ename || ' is a ' || job from emp;
- select empno, ename || '''s annual salary is ' || sal*12 from emp;
- select '姓名:' || ename || ', 工作: ' || job from emp;
使用欄位別名
* 欄位別名
- 重新命名查詢結果中的欄位,以增強可讀性
- 如果別名中使用特殊字元,或者是強制大小寫敏感需使用雙引號
* 語法格式:
- SELECT <欄位名>|<表示式>[[AS]<欄位別名>],...
- FROM <表名>;
* 用法舉例:
- select empno as 員工編號, ename 員工姓名, sal*12 "年 薪" from emp;
- select empno, ename "Ename", sal*12 "Anual Salary" from emp;
空值
* 什麼是空值
- 空值是無效的,未指定的,未知的或不可預知的值
- 空值不等同於空格或者0
* 空值舉例:
- select empno, ename, job, sal, comm from emp;
##########[ 在表示式中使用空值 ]##########
* 算術表示式中如果出現空值,則整個表示式結果為空
* 連線表示式中出現的空值被當作一個空的(長度為零的)字串處理
- select empno, ename, sal, comm, ename || ' - ' || comm, sal+comm from emp;
去除重複行
* 在預設情況下,查詢結果中包含所有符合條件的記錄行,名括重複行.
- select deptno from emp;
* 使用 DISTINCT 關鍵字可林查詢結果中清除重複行
- select distinct deptno from emp;
* DISTINCT 的作用範圍是後面所有欄位的組合
- select distinct deptno, job from emp;
查詢結果排序
* 查詢結果預設按照記錄的插入順序進行排序
* 也可使用 ORDER BY 子句對查詢結果進行排序,排序方式包括升序(ASC, 預設)和降序(DESC)兩種:
- select empno, ename, sal from emp order by sal;
- select empno, ename, sal from emp order by sal desc;
* 按多欄位排序
- select deptno, empno, ename, sal from emp order by deptno, sal;
* 使用欄位別名排序
- select empno, ename, sal*12 annsal from emp order by annsal;
根據NULL排序
elect deptno, empno, ename, sal from emp order by nulls last;
條件查詢
* 查詢所有 deptno=10 的資料
- select * from emp where deptno=10;
* 語法格式
- SELECT *|{[DISTINCT]<欄位名>|<表示式>[<別名>],...}
- FROM <表名>
- [WHERE <查詢條件>];
* 查詢語句中使用字串和日期
- 字串和日期值要用單引擴起來
- 字串大小寫敏感
- 日期值格式敏感,預設的日期格式是'DD-MON-RR'
- select * from emp where ename='SMITH';
- select * from emp where hiredate='02-4月-81';
* 獲取當前預設日期格式
- select sysdate from dual;
比較運算子
* 運算子 含 義
- = 等 於
- > 大 於
- >= 大於等於
- < 小於
- <= 小於等於
- <> 大等於
* 查詢所有 sal > 2900 的資料
- select * from emp where sal > 2900;
* 查詢所有 deptno <> 20 的資料
- select * from emp where deptno <> 20;
- select * from emp where job <> 'MANAGER';
--------------------------------------------------
* 運算子 含 義
- BETWEEN...AND... 界於兩值之間(包括邊界,注意:小值在前面)
- IN(set) 出現在集合中
- LIKE 模糊查詢
- IS NULL 為空值
* 查詢工資(sal) 在1600-2900之間的資料
- select * from emp where sal between 1600 and 3200;
- select * from emp where sal between 1600 and 3200 order by sal;
- select * from emp where sal between 1600 and 3200 order by sal desc;
- select distinct deptno, sal from emp where sal between 1600 and 3200 order by sal;
* 查詢姓名(ename)出現在('SMITH', 'CLARK', 'KING', 'TOM')裡的資料
- select * from emp where ename in('SMITH', 'CLARK', 'KING', 'TOM');
* 查詢姓名(ename)不出現在('SMITH', 'CLARK', 'KING', 'TOM')裡的資料
- select * from emp where ename not in('SMITH', 'CLARK', 'KING', 'TOM');
模糊查詢
* 使用 LIKE 運算子執行模糊查詢(通配查詢)
- % 表示零或多個字元
- _表示一個字元
- 對於特殊符號可使用 ESCAPE 識別符號來查詢
* 查詢姓名(ename)是'S'開頭的資料
- select * from emp where ename like 'S%';
* 查詢姓名第個字是'A'的資料
- select * from emp where ename like '_A%';
* 查詢姓名有下劃線'_'的資料
- select * from emp where ename like '%\_%' escape '\';
判斷空值
* 使用 IS NULL 運算子進行空值判斷
* 查詢 comm 為空的資料
- select * from emp where comm is null;
* 查詢 comm 不為空的資料
- select * from emp where comm is not null;
邏輯運算子
* 運算子 含 義
- AND 邏輯"與"
- OR 邏輯"或"
- NOT 邏輯"非"
* 注意:如果三個邏輯運算子同時用上,則優先順序:NOT>AND>OR
* 查詢部門編號(deptno)等於20並且工資(sal)大於2000的資料
- select * from emp where deptno=20 and sal>2000;
* 查詢部門編號(deptno)等於20或者工資(sal)大於2000的資料
- select * from emp where deptno=20 or sal>2000;
* 查詢部門編號(deptno)出現在(20, 30, 40)的資料
- select * from emp where deptno in(20, 30, 40);
* 查詢部門編號(deptno)不出現在(20, 30, 40)的資料
- select * from emp where deptno not in(20, 30, 40);
運算子優先順序
* 優先順序 運算子
- 1 *, /
- 2 +, -
- 3 ||
- 4 =, >, >=, <, <=, <>
- 5 IS [NOT] NULL, LIKE, [NOT] IN
- 6 [NOT]BETWEEN..AND..
- 7 NOT
- 8 AND
- 9 OR
* 可使用小括號強行改變運算順序
- select * from emp where job='SALESMAN' or job='CLERK' and sal>=1280;
- select * from emp where (job='SALESMAN' or job='CLERK') and sal>=1280;
3.Oracle主要資料型別
* 資料型別 說明
- char 字元型,最大長度2000B,預設長度為1B
- nchar 基於NLS國家字符集的字元型,最大長度2000B,預設為1字元
- varchar2…………變長字元型,最大長度4000B
- nvarchar2 基於NLS國家字符集的字元型,其餘同varchar2
- varchar 同varchar2
- number(m, n)……數值型,m為總位數,n為小數位數,總長度最大為38位
- date………………日期型,有效表數範圍:公元前4712年1月1到公元后4712年12月31日
- long 變長字元型,最大長度2GB,不支援對字串內容進行搜尋
- raw 變長二進位制資料型別,最大長度2000B
- long raw 變長二進位制資料型別,最大長度2GB
- blob………………二進位制大物件型別,最大長度4GB
- clob………………字元大物件型別,最大長度4GB
- nclob 基於NLS國家字符集的字元大物件型別,最大長度4GB
- bfile 在資料庫外部儲存的大型二進位制檔案大物件型別,最大長度4GB
* 測試1(char)
* 注意:位單為位元組(不夠指定長度也算指定長度空間)
- create table t1(name char(10),sex char(1));
- insert into t1 values('tom', 'm');(Y)
- insert into t1 values('tom', '男');(N)
- insert into t1 values('一二三四五', 'f');(Y)
- insert into t1 values('一二三四五六', 'f');(N)
* 測試2(nchar)
* 注意:位單為字元
- create table t2(name nchar(10), sex nchar(1));
- insert into t2 values('tom', '男');(Y)
- insert into t3 values('一二三四五六', 'f');(Y)
- insert into t2 values('一二三四五六七八九十', '男');(Y)
- insert into t2 values('一二三四五六七八九十一', '男');(N)
- insert into t2 values('一二三四五六七八九十', '男性');(N)
* 測試3(varchar2)(2000箇中文,4000個英文)
* 注意:位單為位元組(長度為資料的長度,超過長度報錯)
- create table t3(name varchar2(10), sex varchar(2));
- insert into t3 values('一二三四五', '男');(Y)
- insert into t3 values('一二三四五六', '男');(N)
- insert into t3 values('一二三四五', '男性');(N)
- insert into t3 values('abcdefghij', 'aa');(Y)
- insert into t3 values('abcdefghijk', 'aa');(N)
- insert into t3 values('abcdefghij', 'aaa');(N)
- insert into t3 values('abcdefghij', 'a');(N)
- insert into t3 values('ABCDEFGHIJ', 'AA');(Y)
* 測試4(number)
* 注意:小數只保留指定位數
- create table t4(name varchar2(10), sal number(7, 2));
- insert into t4 values('AAA', 2.6);(Y)
- insert into t4 values('AAA', 11111.66);(Y)
- insert into t4 values('AAA', 123456.12);(N)
- insert into t4 values('AAA', 12456.123456);(Y)
* 測試5(date)
- create table t5(name varchar2(10), birth date);
- insert into t5 values('BBB', sysdate);(Y)
- insert into t5 values('BBB', '03-8月 -09');(Y)
4.函式
* Oracle 函式分為單行函式和多行函式兩大類
* 單行函式
- 操作資料項
- 接受引數並返回處理結果
- 對每一返回行起作用
- 可修改資料型別
- 可巢狀使用
* 單行函式分類
- 字元函式
- 數值函式
- 日期函式
- 轉換函式
- 通用函式
字元函式
* 字元大小寫轉換函式
* 函式 功能 用法 返回結果
- lower() 轉換為小寫 lower('John Smith') john smith
- upper() 轉換為大寫 upper('John Smith') JOHN SMITH
- initcap() 單詞首字母大寫 initcap('JOHN smith') John Smith
* 例:
- select lower('John Smith') from dual;->(john smith)
- select upper('John Smith') from dual;->(JOHN SMITH)
- select initcap('JOHN smith') from dual;->(John Smith)
*字元處理函式
* 函式 功能 用法 返回結果
- concat() 字串連線 concat('Hello', 'World') Hello World
- substr() 擷取子串 substr('HelloWorld', 4, 3) loW
- length() 返回字串長度 length('Hello World') 11
- instr() 定位子串 instr('Hello World', 'or') 8
- lpad() 左側填充 lpad('Smith', 10, '*') *****Smith
- rpad() 右側填充 rpad('Smith', 10, '*') Smith*****
- trim() 過濾首尾空格 trim(' Mr Smith ') Mr Smith
- replace() 替換 replace('ABA', 'A', 'C') CBC
* 注意:函式可巢狀使用
* 例:
- select concat('Hello', 'World') from dual;->(HelloWorld)
- select concat(concat(ename, ' is a '), job) info from emp where empno=7369;->(SMITH is a CLERK)
- select substr('HelloWorld', 4, 3) from dual;->(loW)
- select substr(substr('HelloWorld', 3, 6), 3, 3) from dual->(oWo)
- select length('Hello World') from dual;->(11)
- select instr('Hello World', 'or') from dual;->(8)
- select lpad('Smith', 10, '*') from dual;->(*****Smith)
- select rpad('Smith', 10, '*') from dual;->(Smith*****)
- select trim(' Mr Smith ') from dual;->(Mr Smith)
- select replace('ABA', 'A', 'C') from dual;->(CBC)
數值函式
* 函式 功能 用法 返回結果
- abs() 取絕對值 abs(-3.14) 3.14
- round() 四捨五入 round(3.1415) 3
round(3.1415, 3) 3.142
round(314.1592, -2) 300
- trunc() 截斷 trunc(3.1415, 3) 3.141
- ceil() 向上取整 ceil(3.14) 4
- floor() 向下取整 floor(3.14) 3
- sign() 判斷數值正負 sign(-3.14) -1
- sin().. 三角函式.. sin(3.14) .001592653
- power() 冪運算 power(4.5, 2) 20.25
- sqrt() 開平方根 sqrt(9) 3
- mod() 取模 mod(10, 3) 1
- exp() 基數為e的冪運算 exp(1) 2.71828183
- log() 對數運算 log(4, 16.0) 2
- ln() 自然對數運算 ln(7) 1.94591015
* 例:
- select abs(-3.14) from dual;->(3.14)
- select round(3.1415) from dual;->(3)
- select round(3.1415, 3) from dual;->(3.142)
- select round(314.1592, -2) from dual;->(300)
- select trunc(3.1415, 3) from dual;->(3.141)
- select trunc(3.1415, -3) from dual;->(0)
- select trunc(3.1415, 7) from dual;->(3.1415)
- select ceil(3.14) from dual;->(4)
- select floor(3.14) from dual;->(3)
- select sign(-3.14) from dual;->(-1)
- select sin(3.14) from dual;->(.001592653)
- select power(4.5, 2) from dual;->(20.25)
- select sqrt(9) from dual;->(3)
- select mod(10, 3) from dual;->(1)
- select exp(1) from dual;->(2.71828183)
- select log(4, 16.0) from dual;->(2)
- select ln(7) from dual;->(1.94591015)
日期型別
* 關於日期型別
- Oracle內部以數字格式儲存日期和時間資訊:世紀,年,月,日,小時,分鐘,秒
- 預設的日期格式是DD-MON-YY
- 可使用sysdate函式獲取當前系統日期和時間
* 日期型資料的算術運算
- 日期型資料可以直接加或減一個數值,結果仍為日期
- 兩個日期型資料可以相減,結果為二者相差多少天
* 查詢200-12-25減1991-12-25一共有多少天
- select to_date('25-12月 -09') - to_date('25-12月 -1991') from dual;
日期函式
* 函式 功能 用法 返回結果
- add_months(x, y) 計算在日期x基礎上增加y個月後的日期 add_months(sysdate, 2)
- last_day(x) 返回日期x當月最後一天的日期 last_day(sysdate)
- months_between(x, y) 返回日期x和y之間相差的月數 months_between(sysdate, hiredate)
- round(x, y) 將日期x四捨五入到y所指定的 round(sysdate, 'month')
日期單位(月或年)的第一天 round(sysdate, 'year')
- trunc(x, y) 將日期x截斷到y所指定的 trunc(sysdate, 'month')
日期單位(月或年)的第一天 trunc(sysdate, 'year')
- next_day 計算指定日期x後的第一個星期幾 next_day(sysdate, '星期二')
(由引數y指定)對應的日期
* 例:
- select add_months(sysdate, 2) from dual;->(05-10月-09)
- select last_day(sysdate) from dual;->(31-8月 -09)
- select hiredate, months_between(sysdate, hiredate) from emp;
- select months_between(sysdate, '17-12月-80') from dual;->(343.63907)
- select round(sysdate, 'month') from dual;->(01-8月 -09)
- select round(to_date('16-8月 -09'), 'month') from dual;->(01-9月 -09)
- select round(sysdate, 'year') from dual;->(01-1月 -10)
- select round(to_date('1-7月 -09'), 'year') from dual;->(01-1月 -10)
- select round(to_date('25-6月 -09'), 'year') from dual;->(01-9月 -09)
- select trunc(sysdate, 'month') from dual;->(01-8月 -09)
- select trunc(sysdate, 'year') from dual;->(01-1月 -09)
- select next_day(sysdate, '星期二') from dual;->(11-8月 -09)
- select next_day(next_day(sysdate, '星期二'), '星期二') from dual;->(18-8月 -09)
轉換函式
* 資料型別轉換包括隱含轉換和顯式轉換兩方式,建議使用顯式的資料型別轉換,確保SQL語句的可靠性
* 字元型別 -> 數值型別 -> to_number()
* 字元型別 -> 日期型別 -> to_date()
* 數值型別 -> 字元型別 -> to_char()
* 日期型別 -> 字元型別 -> to_char()
日期 -> 字串
* to_char()函式可以將日期型數值轉換為字串形式
* 格式:
- to_char(date) // 預設轉換為'dd-mm-yy'格式
- to_char(date, 'format_model') // 轉換為模式串指定的格式
* 例:
- select empno, ename, sal, to_char(hiredate, 'yyyy-mm-dd') from emp;
- select to_char(sysdate, 'yyyy-mm-dd hh:mi:ss') from dual;
- select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;
常用日期格式符
* 格式符 說明 舉列
- yyyy 年份 2008
- mm 用數字顯示月份 02
- dd 在當月中是第幾天 28
- day 星期幾 星期五
- am/pm 顯示上午/下午 上午
- hh/hh12/hh24 小時 2:30 14:30
- mi 分鐘 30
- ss 秒鐘 46
* 說明:除上述格式符外,日期模式串中還可直接出現如下字元( - : ; / );
* 如要顯示其它文字字串則需使用雙引號括起來;也可在械串的開頭使用"fm"標
* 記以去掉數字前面的零
* 例:
- select to_char(sysdate, 'yyyy"年"mm"月"dd"日" day hh24:mi:ss') from dual;
- select to_char(sysdate, 'fmyyyy"年"mm"月"dd"日" day hh24:mi:ss') from dual;
字串 -> 日期
* to_date()函式可以將字串轉換為日期型數值形式
* 格式:
- to_date(char) // 按預設格式'dd-mm-yy'進行解析
- to_date(char, 'format_model') // 按模式串指定的格式進行解析
* 例:
- insert into t5 values('BOBO', to_date('2008-02-28', 'yyyy-mm-dd'));
- select to_date(to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') from dual;
- select to_char(to_date(to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'), 'dd/mm/yyyy') from dual;
數字
* to_char()函式可以將數字值轉換為字串形式
* 格式:
- to_char(number)
- to_char(number, 'format_model')
* 例:
- select to_char(12345.678901) from dual;
- select to_char(12345.678901, '$99,999.0000') from dual;
* 數字模式符:
* 格式符 說 明
- 9 代表一位數字
- 0 代表一位數字,強制顯示0
- $ 放置一個美圓符$
- L 放置一個本地貨幣符
- . 小數點
- , 千位指示符
* 例:
- select to_char(12345.6, 'L999,999.0000') from dual;
字串 -> 數字
* to_number()函式可以將字串轉換為數字值形式
* 格式:
- to_number(char)
- to_number(char, 'format_model')
* 例:
- select to_number('12345.678901') from dual;
- select to_number('$12,345.6789', '$99,999.0000') from dual;
通用函式
* 通用函式適用於任何型別資料(包括空值):
- nvl()
- nvl2()
- nullif()
- coalesce()
- case表示式
- decode()
NVL()函式
* NVL()函式用於將空值null替換為指定的預設值,適用於字元,數字,日期等型別資料
* 語法格式:
- NVL(exp1, exp2)
* 說明:
- 如果表示式exp1的值為null,則返回exp2的值,否則返回exp1的值
* 用法舉例:
- select empno, ename, sal, comm, sal+nvl(comm, 0) from emp;
- select empno, ename, hiredate, nvl(hiredate, sysdate) from emp;
- select empno, ename, job, nvl(job, 'NO job yet') from emp;
NVL2()函式
* NVL2()函式用於實現條件表示式功能
* 語法格式:
- NVL2(exp1, exp2, exp3)
* 說明:
- 如果表示式exp1的值不為null,則返回exp2的值,否則返回exp3的值
* 用法舉例:
- select empno, ename, sal, comm, nvl2(comm, sal+comm, sal) from emp;
NULLIF()函式
* NULLIF()函式用於資料等價性比較並根據比較結果返回null或其中一個被比較的數值
* 語法格式:
- NULLIF(exp1, exp2)
* 說明:
- 如果表示式exp1與exp2的值相等返回null,否則返回exp1的值
* 用法舉例:
- select name 原名, nullif(pen_name, name) 化名 from author;
COALESCE()函式
* COALESCE()函式用於實現資料"接合"功能
* 語法格式:
- COALESCE(exp1, exp2, ...)
* 說明:
- 依次考察各引數表示式,遇到非null值即停止並返回該值
* 用法舉例:
- select empno, ename, sal, comm, coalesce(sal+comm, sal, 0) 總收入 from emp;
CASE()函式
* CASE()表示式用於實現多路分支結構
* 語法格式:
- CASE exp1 when comparison_exp1 then return_exp1
- [when comparison_exp2 then return_exp2
- when comparison_expn then return_expn
- else esle_exp]
- end [TempName]
* 說明:
- 如果 exp1 是 comparison_exp1 的時候,就返回 return_exp1
- [ comparison_exp2 的時候,就返回 return_exp2
- comparison_expn 的時候,就返回 return_expn
- else 就返回 esle_exp ]
- end [別名]
* 用法舉例:
- select empno, ename, sal,
- case deptno when 10 then '財務部'
- when 20 then '研發部'
- when 30 then '銷售部'
- else '未知部門'
- end 部門
- from emp;
DECODE()函式
* 和CASE()表示式類似,DECODE()函式也用於實現多路分支結構
* 語法格式:
- decode(col|expression, search1, result1
- [, search2, result2, ...,]
- [, default])
* 說明:
- 如果 col|expression 是 search1 的時候,就返回 result1
- [ search2 的時候,就返回 result2, ...]
- [, default])
- [別名]
* 用法舉例:
- select empno, ename, sal,
- decode(deptno, 10, '財務部',
- 20, '研發部',
- 30, '銷售部',
- '未知部門')
- 部門
- from emp;
函式巢狀
* 單行孫數可以巢狀使用, 巢狀層次無限制
* 巢狀函式的執行順序是由內到外
- select empno, lpad(initcap(trim(ename)), 10, '*') name, job, sal from emp;
##########[ 單行函式小結 ]##########
* 使用系統提供的單行函式可實現如下功能:
- 對資料進行計算
- 控制資料的輸出格式
- 設定/改變日期的顯示格式
- 進行資料型別轉換
- 使用NVL函式處理空值
- 實現IF-THEN-ELSE多路分支邏輯
分組函式
* 分組函式對一組資料進行運算,針對一組資料(多行記錄)只返回一個結果,也稱多行函式
* 常用分組函式
- 函式 功能說明 適用型別
- avg() 計算平均值 數值型
- count() 返回查詢所行到的記錄行數 任何型別資料
- max() 計算最大值 任何型別資料
- min() 計算最小值 任何型別資料
- sun() 求和 數值型
* 舉例:
- select avg(sal), max(sal), min(sal), sum(sal) from emp;
- select max(hiredate), min(hiredate) from emp;
COUNT()函式
* count(*) 返回組中總記錄數目
* count(exp) 返回表示式exp值非空的記錄數目
* count(distinct(exp)) 返回表示式exp值不重複的, 非空的記錄數目
* 舉例:
- select count(*) from emp;
- select count(comm) from emp;
- select count(distinct(deptno)) from emp;
分組函式與空值
* 分組函式省略列中的空值
- select avg(comm) from emp;
- select sum(comm) from emp;
* 可使用NVL()函式強制分組函式處理空值
- select avg(nvl(comm, 0)) from emp;
GROUP BY子句
* GROUP BY 子句將表中資料分成若干小組
* 語法格式
- select column, group_function(column)
- from table
- [where condition]
- [group by group_by_expression]
- [order by column]
* 例:
- select deptno, avg(sal) from emp group by deptno;
- select deptno, avg(sal) from emp where deptno > 10 group by deptno;
- select deptno, avg(sal) from emp group by deptno order by deptno desc;
* 說明:
- 出現在SELECT列表中的欄位,如果不是包含在組函式中,那麼該欄位必須同時在 GROUP BY 子句中出現
- 包含在 GROUP BY 子句中的欄位則不必須出現在 SELECT 列表中
- 可使用 where 子句限定查詢條件
- 可使用 order by 子句指定排序方式
* 注意:
- 執行順序: where -> group by -> select ... from ... -> order by..
##########[ 基於多欄位分組 ]##########
- select deptno, job, avg(sal) from emp group by deptno, job;
##########[ 組函式的錯誤用法 ]##########
* 如果沒有 GROUP BY 子句, SELECT 列表中不允許出現欄位(單行函式)與分組函式混用的情況
- select empno, sal from emp; -> (Y)
- select avg(sal) from emp; -> (Y)
- select empno, initcap(ename), avg(sal) from emp; -> (N)
* 不允許在 WHERE 子句中使用分組函式
- select deptno, avg(sal)
- from emp
- where avg(sal) > 2000; -> (N)
- group by deptno;
- 注:這跟子句執行順序有關,
- where 最先執行,
- 在執行 where 子句時,
- 還沒有執行 group by 子句,
- 還不知道什麼分組,
- 也沒計算過 avg(sal) 組內的平均工資
HAVING 子句
* HAVING 子句用於過濾分組
* 語法格式
- select column, group_function(column)
- from table
- [where condition]
- [group by group_by_expression]
- [order by column];
* 例:
- select deptno, job, avg(sal)
- from emp
- where hiredate >= to_date('1981-05-01', 'yyyy-mm-dd')
- group by deptno, job
- having avg(sal) > 1200
- order by deptno, job;
##########[ 分組函式巢狀 ]##########
* 分組函式最多可巢狀兩層
- select max(avg(sal))
- from emp
- group by deptno;
Oracle 表連線
* SQL/Oracle 使用表連線從多個表中查詢資料
* 語法格式:
- select 欄位列表
- from table1, table2
- where table1.column1 = table2.column2
* 說明:
- 在 where 子句中指定連線條件
- 當被連線的多個表中存在同名欄位時,必須在該欄位前加上"表名."作為字首
* 例:
- select empno, ename, job, emp.deptno, dname
- from emp, dept
- where emp.deptno = dept.deptno;
* 提示:加上字首可以提高效率
##########[ 連線的型別 ]##########
* Oracle8i之前的表連線
- 等值連線(Equijoin)
- 非等值連線(Non-Equijoin)
- 外連線(Outer join)
- 左外連線
- 右外連線
- 自連線(Selfjoin)
* Oracle9i新引入的連線形式(支援SQL99規範):
- 交叉連線(Cross join)
- 自然連線(Natural join)
- 使用 Using 子句建立連線
- 使用 On 子句建立連線
- 外連線(Outer join)
- 左外連線
- 右外連線
- 全外連線
##########[ 多表連線 ]##########
* 多表連線中:
- 可使用 AND 操作符增加查詢條件
- 使用表別名可以簡化查詢
- 使用表名(表別名)字首可提高查詢效率
- 為了連線 n 個表, 至少需要 n-1 個連線條件
##########[ 等值連線(Equijion) ]##########
* 什麼是等值連線
- select empno, ename, sal, emp.deptno, dname
- from emp, dept
- where emp.deptno = dept.deptno;
##########[ 非等值連線(Not-Equijion) ]##########
* 問題:如何查得每個員工的工資等級
* 方法1:
- select empno, ename, sal, grade, losal, hisal
- from emp, salgrade
- where sal >= losal and sal <= hisal;
* 方法2:
- select empno, ename, sal, grade, losal, hisal
- from emp, salgrade
- where sal between losal and hisal;
##########[ 外連線(Outer jion) ]##########
* 使用外連線可以看到參與連線的某一方不滿足連線條件的記錄
* 外連線運算子為(+)
* 傳統的外連線分為左外連線和右外邊接兩種
* 語法格式:
- select 欄位列表
- from table1, table2
- where table1.column1(+)=table2.column2;
- select 欄位列表
- from table1, table2
- where table1.column1=table2.column2(+);
* 例:
* 左外連線'(+)'放在右邊,將左表中不符合條件的也顯示出來
- select EMPLOYEE_ID, FIRST_NAME, SALARY, e.DEPARTMENT_ID, DEPARTMENT_NAME
- from employees e, departments d
- where e.DEPARTMENT_ID = d.DEPARTMENT_ID(+)
- order by EMPLOYEE_ID;
* 右外連線'(+)'放在左邊,將右表中不符合條件的也顯示出來
- select EMPLOYEE_ID, FIRST_NAME, SALARY, e.DEPARTMENT_ID, DEPARTMENT_NAME
- from employees e, departments d
- where e.DEPARTMENT_ID(+) = d.DEPARTMENT_ID
- order by EMPLOYEE_ID;
##########[ 自連線(Self jion) ]##########
* 問題:如何查得每個員工及其上司的工號和姓名
- select a.empno, a.ename, a.mgr, b.ename
- from emp a, emp b
- where a.mgr = b.empno
- order by a.empno;
##########[ SQL99 連線語法 ]##########
* SQL1999 規範中規定的連線查詢語法
- select 欄位列表
- from table1
- [cross join table2] |
- [natural join table2] |
- [join table2 using(欄位名)] |
- [join table2 on(table.column_name = table2.column_name)] |
- [(left | right | full outer) join table2
- on(table1.column_name = table2.column_name)];
##########[ 交叉連線(Cross join) ]##########
* Cross join產生了一個笛卡爾集,其效果等同於在兩個表進行連線時未使用 WHERE 子句陰定連線條件
* 舉例:
- select empno, ename, sal, emp.deptno, dname
- from emp cross join dept;
##########[ 自然連線(Natural join) ]##########
* Natural join 基於兩個表中的全部同名列建立連線
- 從兩個表中選出同名列的值均對應相等的所有行
- 如果兩個表中同名列的資料型別不同,則出錯
- 不允許在參照列上使用表名或者別名作為字首
* 舉例:
- select empno, ename, sal, deptno, dname
- from emp natural join dept;
- 上面SQL語句等同於:
- select empno, ename, sal, emp.deptno, dname
- from emp, dept
- where emp.deptno = dept.deptno;
* 注意:第一種方法的deptno不能加上表名字首,第二種方法必須加上表名字首
Using 子句
* 如果不希望參照被連線表的所有同名列進行等值連線,自然連線將無法滿足
* 要求,可以在連線時使用Using子句來設定用於等值連線的列(參照列)名.
* 舉例:
- select empno, ename, sal, deptno, dname
- from emp join dept
- using(deptno);
* 不允許在參照列上使用表名或者別名作為字首
On 子句
* 如果要參照非同名的列進行等值連線,或想設定任意的連線條件,可以使用 ON 子句
* 舉例:
- select empno, ename, sal, emp.deptno, dname
- from emp join dept
- on(emp.deptno = dept.deptno);
* 必須加上表名字首(emp.deptno)
- 上面SQL語句等同於:
- select empno, ename, sal, emp.deptno, dname
- from emp, dept
- where emp.deptno = dept.deptno;
--------------------------------------------------
- select empno, ename, sal, emp.deptno, dname
- from emp join dept
- on(emp.deptno = dept.deptno and sal > 2500);
- 上面SQL語句等同於:
- select empno, ename, sal, emp.deptno, dname
- from emp, dept
- where emp.deptno = dept.deptno and sal > 2500;
多表連線
* 使用SQL99連線語法,兩個以上的表進行連線時應依次/分別指定相臨的兩個表之間的連線條件
* 語法格式:
- select 欄位列表
- from table1
- [cross join table2] |
- [natural join table2] |
- [join table2 using(欄位名)] |
- [join table2 on(table1.column_name=table2.column_name)] |
- [(left | right | full outer) join table2
- on(table1.column_name=table2.column_name)]
- [cross join table3] |
- [natural join table3] |
- [join table3 using(欄位名)] |
- [join table3 on(table2.colimn_name=table3.column_name)] |
- [(left | right | full outer) join table3
- on(table2.column_name=table3.column_name)];
* 舉例:
- SELECT EMPLOYEE_ID, FIRST_NAME, SALARY, DEPARTMENT_ID, DEPARTMENT_NAME, LOCATION_ID, CITY
- FROM EMPLOYEES JOIN DEPARTMENTS USING(DEPARTMENT_ID) NATURAL JOIN LOCATIONS;
- 上面SQL語句等同於:
- SELECT EMPLOYEE_ID, FIRST_NAME, SALARY, DEPARTMENT_ID, DEPARTMENT_NAME, LOCATION_ID, CITY
- FROM EMPLOYEES JOIN DEPARTMENTS USING(DEPARTMENT_ID) JOIN LOCATIONS USING(LOCATION_ID);
- 等同於:
- SELECT EMPLOYEE_ID, FIRST_NAME, SALARY, emp.DEPARTMENT_ID, DEPARTMENT_NAME, LOCATION_ID, CITY
- FROM EMPLOYEES emp JOIN DEPARTMENTS dep ON(emp.DEPARTMENT_ID = dep.DEPARTMENT_ID)
- JOIN LOCATIONS loc USING(LOCATION_ID);
- 等同於:
- SELECT EMPLOYEE_ID, FIRST_NAME, SALARY, emp.DEPARTMENT_ID, DEPARTMENT_NAME, dep.LOCATION_ID, CITY
- FROM EMPLOYEES emp JOIN DEPARTMENTS dep ON(emp.DEPARTMENT_ID = dep.DEPARTMENT_ID)
- JOIN LOCATIONS loc ON(dep.LOCATION_ID = loc.LOCATION_ID);
內連線和外連線
* 內連線(Inner Join)
- 在 SQL99 規範中,內連線只返回滿足連線條件的資料
* 外連線(Outer Join)
- 左外聯接(Left Outer Join)
- 兩個表在連線過程中除返回滿足連線條件的行以外,還返回左表中不滿足條件的行,