Oracle筆記(一)

1.數據庫的邏輯和物理結構

wps_clip_image-28078

  • 表空間由多個數據文件組成sql

  • 數據文件只能屬於一個表空間數據庫

  • 表空間爲邏輯概念,數據文件爲物理概念編程

  • 段存在於表空間中瀏覽器

  • 段是區的集合服務器

  • 區是數據塊的集合編程語言

  • 數據塊會被映射到磁盤塊ide

 

2.用戶登陸函數

登陸普通用戶:性能

方式一:執行 sqlplus --> 輸入用戶名 --> 輸入密碼。學習

方式二:執行 sqlplus {用戶名} --> 輸入密碼。

方式三:執行 sqlplus {用戶名}/{密碼}。

例子:

sqlplus --> 輸入scott --> 輸入tiger。

sqlplus scott --> 輸入密碼。

sqlplus scott/tiger。

登陸管理員:

執行 sqlplus / as sysdba

退出:

exit

 

3.修改權限

¨ 解鎖用戶:

alter user 用戶名 account unlock;

¨ 鎖定用戶:

alter user 用戶名 account lock;

¨ 修改密碼:

alter user 用戶名 identified by 新密碼;

¨ 修改管理員密碼:

alter user sys identified by 新密碼;

 

4.Oracle相關的服務

OracleService+服務名,該服務是數據庫啓動的基礎,只有該服務啓動了,Oracle數據庫才能正常啓動。這是必須啓動的服務。

OracleOraDb10g_home1TNSListener,該服務是服務器端爲客戶端提供的監聽服務,只有該服務在服務器上正常啓動,客戶端才能鏈接到服務器。該監聽服務接收客戶端發出的請求,而後將請求傳遞給數據庫服務器。一旦創建了鏈接,客戶端和數據庫服務器就能直接通訊了。

OracleOraDb10g_home1iSQL*Plus,該服務提供了用瀏覽器對數據庫中數據操做的方式。該服務啓動後,就可使用瀏覽器進行遠程登陸並進行數據庫操做了。

 

SQL能夠分紅如下幾組:

  • DML(Data Manipulation Language) 數據操做語言,用於檢索或者修改數據
  • DDL(Data Definition Language) 數據定義語言,用於定義數據的結構,建立、修改或者刪除數據庫對象
  • DCL(Data Control Language) 數據控制語言,用於定義數據庫的權限

簡單查詢指的是查詢出一張表中的全部的數據,簡單查詢的語法以下:

5.查詢

1、簡單查詢

SELECT [DISTINCT] * | 字段 [別名] [,字段 [別名]] FROM 表名稱 [別名];

查詢出來的內容中出現了重複的數據,而之因此數據會有重複,主要的緣由是如今沒有消除掉重複記錄,可使用DISTINCT消除掉全部的重複內容:

SELECT DISTINCT job FROM emp;

在簡單查詢中也可使用「||」鏈接查詢的字段。

範例:觀察「||」的使用

SELECT empno || ',' || ename FROM emp;

2、限定查詢

在以前的簡單查詢中,是將全部的記錄進行顯示,可是如今能夠對顯示的記錄進行過濾的操做,而這就屬於限定查詢的工做了,限定查詢就是在以前語法的基礎上增長了一個WHERE子句,用於指定限定條件,此時語法以下:

SELECT [DISTINCT] * | 字段 [別名] [,字段 [別名]] FROM 表名稱 [別名] [WHERE 條件(S)];

在WHERE子句以後能夠增長多個條件,最多見的條件就是基本的關係運算:>、>=、<、<=、!=(<>)、BETWEEN、AND、LIKE、IN、IS NULL、AND、OR、NOT

一、關係運算

範例:查詢出全部職位是辦事員的僱員信息

SELECT * FROM emp WHERE job='clerk';

這個時候沒有返回相應的查詢結果,主要緣由是在Oracle數據庫中,全部的數據都是區分大小寫的,因此代碼修改以下:

SELECT * FROM emp WHERE job='CLERK';

二、範圍判斷:BETWEEN…AND…

範例:要求查詢出基本工資在1500~3000的僱員信息

SELECT * FROM emp WHERE sal BETWEEN 1500 AND 3000;

範例:如今也能夠對BETWEEN…AND…操做求反

SELECT * FROM emp WHERE NOT sal BETWEEN 1500 AND 3000;

「BETWEEN…AND…」操做符不光只是針對於數字有用,對於日期也一樣有用。

三、判斷是否爲空:IS (NOT) NULL

使用此語法能夠判斷某一個字段上的內容是不是「null」,可是null和數字0以及空字符串是兩個概念。

範例:查詢出全部領取獎金的僱員信息

SELECT * FROM emp WHERE comm IS NOT NULL; SELECT * FROM emp WHERE NOT comm IS NULL;

範例:查詢出全部不領取獎金的僱員

SELECT * FROM emp WHERE comm IS NULL;
四、指定範圍的判斷:IN操做符

五、模糊查詢:LIKE子句

LIKE子句的功能是提供了模糊查找的操做,例如:某些程序上出現的搜索操做,都屬於LIKE子句的實現,可是必須提醒的,搜索引擎上的查詢可不是LIKE。

可是要想使用LIKE子句則必須認識兩個匹配符號:

匹配單個字符:         _       ->  1個

匹配任意多個字符: %      ->  0個、1個、多個

 

優先級:

wps_clip_image-3049

空值(null)與對空值的處理

¨ 空值是無效的,未指定的,未知的或不可預知的值

¨ 空值不是空格或者0。

¨ 包含空值的數學表達式的值都爲空值

處理字符串與日期

¨ 字符和日期要包含在單引號中。

¨ 字符大小寫敏感,日期格式敏感。

¨ 默認的日期格式是 DD-MON-RR。

 

3、數據的排序

 

SELECT [DISTINCT] * | 字段 [別名] [,字段 [別名]]

FROM 表名稱 [別名]

[WHERE 條件(S)]

[ORDER BY 字段 [ASC|DESC] [,字段 [ASC|DESC],…]];

「ORDER BY」子句是寫在全部的SQL語句最後的內容,並且對於排序有如下幾點說明:

排序的時候能夠指定多個排序的字段;

排序的方式有兩種:

  • 升序(ASC):默認,不寫也是升序;
  • 降序(DESC):用戶須要指定,由大到小排序;

 

單行函數

 

wps_clip_image-4712

1、字符函數

字符函數的功能主要是進行字符串數據的操做,下面給出幾個字符函數:

  • UPPER(字符串 | 列):將輸入的字符串變爲大寫返回;
  • LOWER(字符串 | 列):將輸入的字符串變爲小寫返回;
  • INITCAP(字符串 | 列):開頭首字母大寫;
  • LENGTH(字符串 | 列):求出字符串的長度;
  • REPLACE(字符串 | 列):進行替換;
  • SUBSTR(字符串 | 列,開始點 [,結束點]):字符串截取;

wps_clip_image-5437

wps_clip_image-5319[4]

2、數字函數

  • ROUND(數字 | 列 [,保留小數的位數]):四捨五入的操做;
  • TRUNC(數字 | 列 [,保留小數的位數]):捨棄指定位置的內容;
  • MOD(數字 1,數字2):取模,取餘數;

3、日期函數

取得當前的日期,這個當前日期可使用「SYSDATE」取得,代碼以下:

SELECT SYSDATE FROM dual;

除了以上的當前日期以外,在日期中也能夠進行若干計算:

  • 日期 + 數字 = 日期,表示若干天以後的日期;
SELECT SYSDATE + 3,SYSDATE + 300 FROM dual;
  • 日期 – 數字 = 日期,表示若干天前的日期;
SELECT SYSDATE - 3,SYSDATE - 300 FROM dual;
  • 日期 – 日期 = 數字,表示的是兩個日期間的天數,可是確定是大日期 – 小日期;

範例:求出每一個僱員到今天爲止的僱傭天數

SELECT ename,hiredate,SYSDATE-hiredate FROM emp;

並且不少的編程語言之中,也都會提出一種概念,日期能夠經過數字表示出來。

除了以上的三個公式以外,也提供了以下的四個操做函數:

  • LAST_DAY(日期):求出指定日期的最後一天;

範例:求出本月的最後一天日期

SELECT LAST_DAY(SYSDATE) FROM dual;
  • NEXT_DAY(日期,星期數):求出下一個指定星期X的日期;

範例:求出下一個週一

SELECT NEXT_DAY(SYSDATE,'星期一') FROM dual;
  • ADD_MONTHS(日期,數字):求出若干月以後的日期;

範例:求出四個月後的日期

SELECT ADD_MONTHS(SYSDATE,4) FROM dual;
  • MONTHS_BETWEEN(日期1,日期2):求出兩個日期之間所經歷的月份;

範例:求出每一個僱員到今天爲止的僱傭月份

SELECT ename,hiredate,TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)) FROM emp;

在全部的開發之中,若是是日期的操做,建議使用以上的函數,由於這些函數能夠避免閏年的問題。

4、轉換函數

  • TO_CHAR(字符串 | 列,格式字符串):將日期或者是數字變爲字符串顯示;
  • TO_DATE(字符串,格式字符串):將字符串變爲DATE數據顯示;
  • TO_NUMBER(字符串):將字符串變爲數字顯示;

wps_clip_image-7687

TO_CHAR()函數

SELECT TO_CHAR(SYSDATE,'yyyy-mm-dd'),TO_CHAR(SYSDATE,'yyyy') year, TO_CHAR(SYSDATE,'mm') month, TO_CHAR(SYSDATE,'dd') day FROM dual;
TO_CHAR(SY YEAR MO DA
---------- ---- -- --
2012-08-12 2012 08 12

可是這個時候的顯示數據之中能夠發現會存在前導0,若是要想消除掉這個0的話,能夠加入一個「fm」。

SELECT TO_CHAR(SYSDATE,'fmyyyy-mm-dd') day FROM dual;
DAY
----------
2012-8-12

正常人都加0,因此這個標記知道就好了,但是在Oracle之中,DATE裏面是包含了時間的,可是以前的代碼沒有顯示出時間,要想顯示時間則須要增長標記:

SELECT TO_CHAR(SYSDATE,'fmyyyy-mm-dd hh24:mi:ss') day FROM dual;
DAY
-------------------
2012-8-12 16:13:38

必定要注意,使用TO_CHAR()函數以後,全部的內容都是字符串,再也不是以前的DATE型數據,TO_CHAR()函數也能夠用於數字的格式化上,這個時候每個「9」表示一位數字的概念,而不是數字9的概念。

SELECT TO_CHAR(89078907890,'L999,999,999,999,999') FROM dual;
TO_CHAR(89078907890,'L999,999,
------------------------------
              ¥89,078,907,890

其中的字母「L」,表示的是「Local」的含義,即:當前的所在的語言環境下的貨幣符號。

wps_clip_image-7977

TO_DATE()函數

此函數的主要功能是將一個字符串變爲DATE型數據。

SELECT TO_DATE('1989-09-12','yyyy-mm-dd') FROM dual;
TO_DATE('1989-
--------------
12-9月 -89

5、通用函數

通用函數主要有兩個:NVL()、DECODE()

NVL()函數,處理null

NVL函數將空值轉換成一個已知的值:

l 可使用的數據類型有日期、字符、數字。

l 函數的通常形式:

  • NVL(commission_pct,0)
  • NVL(hire_date,'01-JAN-97')
  • NVL(job_id,'No Job Yet')

 

DECODE()函數:多數值判斷

DECODE()函數很是相似於程序中的if…else…語句,惟一不一樣的是DECODE()函數判斷的是數值,而不是邏輯條件。

例如,如今要求顯示所有僱員的職位,可是這些職位要求替換爲中文顯示:

  • CLERK:辦事員;
  • SALESMAN:銷售;
  • MANAGER:經理;
  • ANALYST:分析員;
  • PRESIDENT:總裁;

這種判斷確定是逐行進行判斷,因此這個時候就必須採用DECODE(),而此函數的語法以下:

DECODE(數值 | 列 ,判斷值1,顯示值1,判斷值2,顯示值2,判斷值3,顯示值3,…)

範例:實現顯示的操做功能

SELECT empno,ename,job,DECODE(job,'CLERK','辦事員','SALESMAN','銷售人員','MANAGER','經理','ANALYST','分析員','PRESIDENT','總裁') FROM emp;
 
 

多表查詢

1、多表查詢的基本概念

SELECT [DISTINCT] * | 字段 [別名] [,字段 [別名] ,…]

FROM 表名稱 [別名], [表名稱 [別名] ,…]

[WHERE 條件(S)]

[ORDER BY 排序字段 [ASC|DESC] [,排序字段 [ASC|DESC] ,…]];

笛卡爾集:學數學的都懂。。

2、鏈接

Oracle 鏈接:

Ø Equijoin:等值鏈接

Ø Non-equijoin:不等值鏈接

Ø Outer join:外鏈接

Ø Self join:自鏈接

SQL: 1999

Ø Cross joins

Ø Natural joins

Ø Using clause

Ø Full or two sided outer joins

1. 等值鏈接

wps_clip_image-11951

wps_clip_image-11991

使用表的別名

l 使用別名能夠簡化查詢。

l 使用表名前綴能夠提升執行效率。

2.鏈接多個表

l 鏈接 n個表,至少須要 n-1個鏈接條件。 例如:鏈接三個表,至少須要兩個鏈接條件。

3. 非等值鏈接

wps_clip_image-12608

wps_clip_image-12637

4.外鏈接(左、右鏈接)

wps_clip_image-12918

wps_clip_image-8470

  • (+)=:放在了等號的左邊,表示的是右鏈接;
  • =(+):放在了等號的右邊,表示的是左鏈接;

可是不用去刻意的區分是左仍是右,只是根據查詢結果而定,若是發現有些須要的數據沒有顯示出來,就使用此符號更改鏈接方向。

 

SQL:1999語法

除了以上的錶鏈接操做以外,在SQL語法之中,也提供了另一套用於錶鏈接的操做SQL,格式以下:

SELECT table1.column,table2.column FROM table1 [CROSS JOIN table2]| [NATURAL JOIN table2]| [JOIN table2 USING(column_name)]| [JOIN table2 ON(table1.column_name=table2.column_name)]| [LEFT|RIGHT|FULL OUTER JOIN table2 ON(table1.column_name=table2.column_name)];

 

以上其實是屬於多個語法的聯合,下面分塊說明語法的使用。

一、交叉鏈接(CROSS JOIN):用於產生笛卡爾積

SELECT * FROM emp CROSS JOIN dept;

笛卡爾積自己並非屬於無用的內容,在某些狀況下仍是須要使用的。

二、天然鏈接(NATURAL JOIN):自動找到匹配的關聯字段,消除掉笛卡爾積

SELECT * FROM emp NATURAL JOIN dept;

可是並非全部的字段都是關聯字段,設置關聯字段須要經過約束指定;

三、JOIN…USING子句:用戶本身指定一個消除笛卡爾積的關聯字段

SELECT * FROM emp JOIN dept USING(deptno);

四、JOIN…ON子句:用戶本身指定一個能夠消除笛卡爾積的關聯條件

SELECT * FROM emp JOIN dept ON(emp.deptno=dept.deptno);

五、鏈接方向的改變:

  • 左(外)鏈接:LEFT OUTER JOIN…ON;
  • 右(外)鏈接:RIGHT OUTER JOIN…ON;
  • 全(外)鏈接:FULL OUTER JOIN…ON; --> 把兩張表中沒有的數據都顯示
SELECT * FROM emp RIGHT OUTER JOIN dept ON(emp.deptno=dept.deptno);
左外聯接

wps_clip_image-13783

右外聯接

wps_clip_image-13937

滿外聯接

wps_clip_image-19637

在Oracle以外的數據庫都使用以上的SQL:1999語法操做,因此這個語法還必須會一些(若是你一直使用的都是Oracle就能夠不會了)。

再次強調:多表查詢的性能確定不高,並且性能必定要在大數據量的狀況下才可以發現。

4、統計函數及分組查詢

一、統計函數

在以前學習過一個COUNT()函數,此函數的功能能夠統計出表中的數據量,實際上這個就是一個統計函數,而經常使用的統計函數有以下幾個:

  • COUNT():查詢表中的數據記錄;
  • AVG():求出平均值;
  • SUM():求和;
  • MAX():求出最大值;
  • MIN():求出最小值;

範例:測試COUNT()、AVG()、SUM()

統計出公司的全部僱員,每月支付的平均工資及總工資。

SELECT MAX(sal),MIN(sal) FROM emp;

注意點:關於COUNT()函數

COUNT()函數的主要功能是進行數據的統計,可是在進行數據統計的時候,若是一張表中沒有統計記錄,COUNT()也會返回數據,只是這個數據是「0」。

SELECT COUNT(ename) FROM BONUS;

若是使用的是其餘函數,則有可能返回null,可是COUNT()永遠都會返回一個具體的數字,這一點之後在開發之中都會使用到。

二、分組查詢

SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 統計函數

FROM 表名稱 [別名], [表名稱 [別名] ,…]

[WHERE 條件(s)]

[GROUP BY 分組字段1 [,分組字段2 ,…]]

[ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]];

可是如今一旦分組以後,實際上對於語法上就會出現了新的限制,對於分組有如下要求:

  • 分組函數能夠在沒有分組的時候單獨用使用,但是卻不能出現其餘的查詢字段;

分組函數單獨使用:

SELECT COUNT(empno) FROM emp;

錯誤的使用,出現了其餘字段:

SELECT empno,COUNT(empno) FROM emp;

  • 若是如今要進行分組的話,則SELECT子句以後,只能出現分組的字段和統計函數,其餘的字段不能出現:

正確作法:

SELECT job,COUNT(empno),AVG(sal)

FROM emp

GROUP BY job;

錯誤的作法:

SELECT deptno,job,COUNT(empno),AVG(sal)

FROM emp

GROUP BY job;

  • 分組函數容許嵌套,可是嵌套以後的分組函數的查詢之中不能再出現任何的其餘字段。

 

此時若是要對分組後的數據再次進行過濾,則使用HAVING子句完成,那麼此時的SQL語法格式以下:

SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 統計函數

FROM 表名稱 [別名], [表名稱 [別名] ,…]

[WHERE 條件(s)]

[GROUP BY 分組字段1 [,分組字段2 ,…]]

[HAVING 分組後的過濾條件(可使用統計函數)]

[ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]];

 

SELECT d.deptno,d.dname,d.loc,COUNT(e.empno) mycount,NVL(AVG(e.sal),0) myavg
FROM dept d,emp e
WHERE d.deptno=e.deptno(+)
GROUP BY d.deptno,d.dname,d.loc
HAVING AVG(sal)>2000;

注意點:WHERE和HAVING的區別

  • WHERE:是在執行GROUP BY操做以前進行的過濾,表示從所有數據之中篩選出部分的數據,在WHERE之中不能使用統計函數;
  • HAVING:是在GROUP BY分組以後的再次過濾,能夠在HAVING子句中使用統計函數;

5、子查詢

子查詢 = 簡單查詢 + 限定查詢 + 多表查詢 + 統計查詢的綜合體;

在以前強調過多表查詢不建議你們使用,由於性能不好,可是多表查詢最有利的替代者就是子查詢,因此子查詢在實際的開發之中使用的至關的多;

所謂的子查詢指的就是在一個查詢之中嵌套了其餘的若干查詢,嵌套子查詢以後的查詢SQL語句以下:

SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 統計函數 ,(

      SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 統計函數

      FROM 表名稱 [別名], [表名稱 [別名] ,…]

      [WHERE 條件(s)]

      [GROUP BY 分組字段1 [,分組字段2 ,…]]

      [HAVING 分組後的過濾條件(可使用統計函數)]

      [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]])

FROM 表名稱 [別名], [表名稱 [別名] ,…] ,(

      SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 統計函數

      FROM 表名稱 [別名], [表名稱 [別名] ,…]

      [WHERE 條件(s)]

      [GROUP BY 分組字段1 [,分組字段2 ,…]]

      [HAVING 分組後的過濾條件(可使用統計函數)]

      [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]])

[WHERE 條件(s) (

      SELECT [DISTINCT] *|分組字段1 [別名] [,分組字段2 [別名] ,…] | 統計函數

      FROM 表名稱 [別名], [表名稱 [別名] ,…]

      [WHERE 條件(s)]

      [GROUP BY 分組字段1 [,分組字段2 ,…]]

      [HAVING 分組後的過濾條件(可使用統計函數)]

      [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]])]

[GROUP BY 分組字段1 [,分組字段2 ,…]]

[HAVING 分組後的過濾條件(可使用統計函數)]

[ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]];

理論上子查詢能夠出如今查詢語句的任意位置上,可是從我的而言,子查詢出如今WHERE和FROM子句之中較多;

如下的使用特色爲我的總結,不是官方聲明的:

  • WHERE:子查詢通常只返回單行列、多行單列、單行多列的數據;
  • FROM:子查詢返回的通常是多行的數據,看成一張臨時表出現。

若是如今的子查詢返回的是多行單列數據的話,這個時候就須要使用三種判斷符判斷了:IN、ANY、ALL;

一、 IN操做符:用於指定一個子查詢的判斷範圍

這個操做符的使用實際上與以前講解的IN是同樣的,惟一不一樣的是,裏面的範圍由子查詢指定了。

SELECT * FROM emp
WHERE sal in (
SELECT sal
FROM emp
WHERE job='MANAGER');

可是在使用IN的時候還要注意NOT IN的問題,若是使用NOT IN操做,在子查詢之中,若是有一個內容是null,則不會查詢出任何的結果。

二、 ANY操做符:與每個內容想匹配,有三種匹配形式

  • =ANY:功能與IN操做符是徹底同樣的;
SELECT * FROM emp
WHERE sal=ANY (
SELECT sal
FROM emp
WHERE job='MANAGER');
  • >ANY:比子查詢中返回記錄最小的還要大的數據;
SELECT * FROM emp
WHERE sal>ANY (
SELECT sal
FROM emp
WHERE job='MANAGER');
  • <ANY:比子查詢中返回記錄的最大的還要小;

三、 ALL操做符:與每個內容相匹配,有兩種匹配形式:

  • >ALL:比子查詢中返回的最大的記錄還要大
SELECT * FROM emp
WHERE sal>ALL (
SELECT sal
FROM emp
WHERE job='MANAGER');
  • <ALL:比子查詢中返回的最小的記錄還要小
SELECT * FROM emp
WHERE sal<ALL (
SELECT sal
FROM emp
WHERE job='MANAGER');

以上的全部子查詢都是在WHERE子句中出現的,那麼下面再來觀察在FROM子句中出現的查詢,這個子查詢通常返回的是多行多列的數據,看成一張臨時表的方式來處理。

使用子查詢的確要比使用多表查詢更加節省性能,因此在開發之中子查詢出現是最多的,並且在給出一個不成文的規定:大部分狀況下,若是最終的查詢結果之中須要出現SELECT子句,可是又不能直接使用統計函數的時候,就在子查詢中統計信息,即:有複雜統計的地方大部分都須要子查詢。

相關文章
相關標籤/搜索