1. 程式人生 > >ORACLE 資料庫的基本操作語句

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(用於修改已有欄位),

Delete, Merge

 

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………………日期型,有效表數範圍:公元前471211到公元后47121231

- 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-251991-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) 返回日期xy之間相差的月數   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)

 

* 說明:

- 如果表示式exp1exp2的值相等返回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)

- 兩個表在連線過程中除返回滿足連線條件的行以外,還返回左表中不滿足條件的行,