天天看點

Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢

  • 一、SQL 語言概述
    • 1.1 SQL 語言簡介
    • 1.2 SQL 語言分類
    • 1.3 SQL 語言編寫規則
  • 二、使用者模式
    • 2.1 模式與模式對象
    • 2.2 示例模式SCOTT
  • 三、基本查詢
    • 3.1 查詢關鍵字介紹
    • 3.2 簡單查詢
    • 3.3 條件查詢
    • 3.4 分組查詢
    • 3.5 排序查詢

一、SQL 語言概述

1.1 SQL 語言簡介

1.1.1 SQL 語言簡介

SQL全稱是結構化查詢語言,英文譯作Structured Query Language,它是一種在關系型資料庫中定義和操縱資料的标準語言。最早是由IBM的聖約瑟研究實驗室為其關系資料庫管理系統SYSTEM R開發的一種查詢語言,當時稱為SEQUEL2,也就是目前的SQL語言。

1979年Oracle公司首先提供了商用的SQL語言,同年,IBM公司在DB2和SQL/DS資料庫系統中也采用了SQL語言。1986年10月,美國國家标準化組織(ANSI)采用SQL作為關系資料庫管理系統的标準語言(ANSI X3.135-1986),後來SQL語言被國際标準化組織(ISO) 采納為國際标準。

随着資料庫技術的發展,SQL 标準也在不斷地進行擴充和修正,資料庫标準委員會先後又推出了SQL-89、SQL-92及SQL-99标準。Oracle在後期的版本中将SQL-99标準內建到了Oracle 9i以後的資料庫中。目前,所有主要關系型資料庫管理系統都支援某個标準的SQL語言,其中大部分資料庫都遵守ANSI SQL 89标準。

1.1.2 SQL 語言特點

SQL是一種非過程化語言,能讓使用者不用考慮諸如資料的存儲格式和資料的存儲路徑等複雜問題就能按照自己的要求在高層資料結構上操作。

SQL 語句通常用于完成一些資料庫的操作任務,具有增加、删除、修改、資料定義與控制等完整的資料庫操作功能。在資料應用程式開發過程中,巧妙地使用SQL語句,可以簡化程式設計,起到事半功倍的效果。

通過SQL語句,程式員或資料庫管理者可以進行如下的主要工作:

  • 建立資料庫的表格,包括設定表格可以使用的空間。
  • 改變資料庫系統環境設定。
  • 針對某個資料庫或表格,授予使用者存取權限。
  • 對資料庫表格建立索引|值。
  • 修改資料庫表格結構(建立、删除或修改表格字段)。
  • 對資料庫進行資料的建立。
  • 對資料庫進行資料的删除。
  • 對資料庫進行資料的修改。
  • 對資料庫進行資料的查詢。

SQL語言結構簡潔,功能強大,簡單易學,自從被國際标準化組織(ISO) 采納為國際标準以後,SQL語言得到了廣泛的應用,它主要有以下特點。

  1. 綜合統一。

    資料庫的主要功能是通過資料庫支援的資料語言來實作的。

  2. 集合性。

    SQL 運作使用者在高層的資料結構上工作,而不對單個記錄進行操作,可操作記錄集。所有SQL語句接受集合作為輸入,傳回集合作為輸出。

    SQL的集合特性允許将一條SQL 語句的結果作為另一條SQL 語句的輸入。

    SQL不要求使用者指定對資料的存放方法。這種特性使使用者更易集中使用者于要得到的結果。不僅查找可以是集合,插入、删除、更新也可以元組。

  3. 統一性。

    SQL為許多任務提供了統一的指令,這樣友善使用者學習和使用,基本的SQL指令隻需很少時間就能學會,甚至最進階的指令也可以在幾天内掌握。

  4. 高度非過程化。

    SQl 是一個非過程化的語言,不像其他的語言,如C、Pascal等,SQL 沒有循環結構(比如if-then-else、 do-while) 以及函數定義等的功能。隻提"做什麼”,不必指明”怎麼做”,使用者無須了解存取路徑及實體位址,這樣減輕使用者負擔,提高效率。因為它一次處理一個記錄, 對資料提供自動導航。而且SQL隻有一一個資料類型的固定設定,換句話說,你不能在使用程式設計語言的時候建立你自己的資料類型。

    存取路徑的選擇由DBMS的優化機制來完成,使用者不必使用循環結構就可以完成資料操作。

  5. 語言簡單,易學易用。

    整個SQL語句隻用9個指令動詞即可以實作對資料庫及資料的查詢和管理。SQL的指令動詞及其功能如圖所示。

    Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢
  6. 以同一種文法結構提供兩種使用方式。

    第一種方式是互動式應答使用,即使用者在終端指令提示符下輸入SQL指令時資料庫伺服器可以立即執行。

    第二種方式是通過預編譯SQL進行執行,即把SQL指令嵌入到應用程式中執行。

  7. 是所有關系資料庫的公共語言。

    于所有主要的關系資料庫管理系統都支援SQL,使用者可将使用SQL的部分從一個RDBMS轉到另-個,所有用SQL編寫的程式都是可移植的。

1.1.3 資料庫的操作任務

資料庫的操作任務通常包括以下幾方面。

  • 查詢資料。
  • 在表中插入、修改和删除記錄。
  • 建立、修改和删除資料對象。
  • 控制對資料和資料對象的讀寫。
  • 保證資料庫一緻性和完整性。

1.2 SQL 語言分類

SQL是關系型資料庫的基本操作語言,是資料庫管理系統與資料庫進行互動的接口。它将資料查詢、資料操縱、事務控制、資料定義和資料控制功能集于一身,而這些功能又分别對應着各自的SQL語言,具體如下。

1.2.1資料查詢語言(DQL)

用于檢索資料庫中的資料,主要是SELECT語句,它在操作資料庫的過程中使用最為頻繁。

1.2.2.資料操縱語言(DML)

用于改變資料庫中的資料,主要包括INSERT、UPDATE和DELETE3條語句。

  • SELECT

    :從一個或多個表和視圖中查詢資料(SELECT),擷取(fetch)操作是可滾動的(scrollable)(見“可滾動遊标”)
  • INSERT

    :向表或視圖中加入新資料行
  • DELETE

    :從表或視圖中删除資料行
  • UPDATE

    :修改表或視圖中已有資料行的列值
  • MERGE

    :根據判斷條件為表及視圖插入或更新資料行
  • EXPLANIN PLAN

    :查詢SQL語句的執行計劃
  • LOCK TABLE

    :對表或視圖加鎖(lock),臨時的限制其他使用者通路此對象

1.2.3.事務控制語言(TCL)

用于維護資料的一緻性,包括COMMIT、 ROLLBACK和SAVEPOINT3條語句。

  • COMMIT

    :将事物對資料的修改永久的儲存到資料庫
  • ROLLBACK

    :取消并還原事物對資料的修改,可還原到事物的開始或任意儲存點(savepoint)
  • SAVEPOINT

    :設定儲存點以辨別復原位置(儲存點)
  • SET TRANSACTION

    :設定事物的屬性

1.2.4.資料定義語言(DDL)

用于建立、修改和删除資料庫對象。比如,可以使用CREATE TABLE語句建立表,使用ALTER TABLE語句修改表結構;使用DROP TABLE語句删除表。

  • CREATE/ALTER/DROP

    :建立/修改/移除方案對象及其他資料結構,包括資料庫自身及資料庫使用者
  • RENAME

    :修改方案對象名稱
  • TRUNCATE

    :修改方案對象的所有資料,但不移除對象的結構
  • GRANT/REVOKE

    :授予或收回權限及角色
  • AUDIT/NOAUDIT

    :打開或關閉審計選項
  • COMMENT

    :向資料字典中添加注釋

1.2.5.資料控制語言(DCL)

用于執行權限授予和權限收回操作,主要包括GRANT和REVOKE兩條指令

  • GRANT

    :用于給使用者或角色授予權限
  • REVOKE

    :用于收回使用者或角色所具有的權限

1.3 SQL 語言編寫規則

1.3.1 SQL 關鍵字

SQL關鍵字不區分大小寫,既可以使用大寫格式,也可以使用小寫格式,或者大小寫格式混用。

示例

select id, name, age from users;
SELECT id, name, age FROM users;
SelecT id, name, age FroM users;
           

上述三種SQL語言方式得到的結果是一緻的。

1.3.2 SQL 對象名和列名

SQL 對象名和列名不區分大小寫,既可以使用大寫格式,也可以使用小寫格式,或者大小寫格式混用。

SELECT id, name, age FROM users;
SELECT ID, NAME, AGE FROM USERS;
SELECT Id, Name, Age FROM Users;
           

上述三種SQL語言方式得到的結果也是一緻的。

1.3.3 SQL 字元值

SQL 對象名和列名區分大小寫,當在SQL中使用要字元值的時候,必須要給出正确的大小寫資料,否則無法得到正确的結果。

SELECT ID, NAME, AGE FROM USERS WHERE NAME = 'JACK';
SELECT ID, NAME, AGE FROM USERS WHERE NAME = 'jack';
           

上述兩種SQL執行的結果是不一樣的,兩者的篩選條件是不同的。

1.3.4 SQL 語句格式化

當我們在編寫SQL語句的時候,如果語句比較短,則可以直接顯示到一行上。但很多時候我們編寫的SQL是很長的,這時就需要将SQL分行顯示,并且以

;

作為整個SQL語句的結束

SELECT id, name, age, sex
  FROM users 
 WHERE nameLIKE 'sys%'
ORDER BY id;
           

二、使用者模式

在Oracle資料庫中,為了便于管理使用者所建立的資料庫對象(如資料表、索引、視圖等),引入了模式的概念,這樣某個使用者所建立的資料庫對象就都屬于該使用者模式。下面将對使用者模式的概念及其執行個體應用進行講解。

2.1 模式與模式對象

2.1.1 模式介紹

模式是一個資料庫對象的集合。模式為一個資料庫使用者所有,并且具有與該使用者相同的名稱,如SYSTEM模式、SCOTT模式等。

在一個模式内部不可以直接通路其他模式的資料庫對象,即使在具有通路權限的情況下,也需要指定模式名稱才可以通路其他模式的資料庫對象。

2.1.2 模式對象介紹

模式對象是由使用者建立的邏輯結構,用以存儲或引用資料。例如,前面章節中所講過的段(如表、索引等),以及使用者所擁有的其他非段的資料庫對象。這些非段的資料庫對象通常包括限制、視圖、同義詞、過程以及程式包等。

簡而言之,模式與模式對象之間的關系就是擁有與被擁有的關系,即模式擁有模式對象,而模式對象被模式所擁有。 一個不為某個使用者所擁有的資料庫對象就不能稱之為模式對象,比如角色、表空間及目錄等資料庫對象。

2.2 示例模式SCOTT

2.2.1 介紹

Oracle提供的SCOTT模式的目的,就是給使用者提供一些示例表和資料來展示Oracle資料庫的一些特性。

SCOTT模式擁有的模式對象(都是資料表)如圖所示。

Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

該模式示範了一個很簡單的公司人力資源管理的資料結構,它也是Oracle的各個版本中一直在沿用的示例模式(當然Oracle 11g還有很多其他示例模式),該使用者模式的連接配接密碼為tiger。

2.2.2 示例

通過連接配接到SCOTT使用者模式,查詢資料字典視圖USER_TABLES可以獲得該模式所包含的資料表,共計4個。

請輸入使用者名:  SCOTT
輸入密碼:

連接配接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

select table_name from user_tables;
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

另外,使用者也可以在SYSTEM模式下查詢SCOTT模式所擁有的資料表,但要求使用dba_tables資料表。

請輸入使用者名:  SYSTEM
輸入密碼:

連接配接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

select table_name from dba_tables where owner = 'SCOTT';
           

三、基本查詢

3.1 查詢關鍵字介紹

使用者對表或視圖最常進行的操作就是檢索資料,檢索資料可以通過SELECT語句來實作,該語句由多個子句組成,通過這些子句可以完成篩選、投影和連接配接等各種資料操作,最終得到使用者想要的查詢結果。該語句的基本文法格式如下:

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

在上面的文法中,共有7個子句,它們的功能分别如下。

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

3.2 簡單查詢

3.2.1 簡單查詢介紹

隻包含SELECT子句和FROM子句的查詢就是簡單查詢,SELECT子句和FROM子句是SELECT語句的必選項,即每個SELECT語句都必須包含這兩個子句。

SELECT子句用于選擇想要在查詢結果中顯示的列,對于這些要顯示的列,即可以使用列名來表示,也可以使用星号

*

來表示。

在檢索資料時,資料将按照SELECT子句後面指定的列名的順序來顯示;如果使用星号

*

,則表示檢索所有的列,這時資料将按照表結構的自然順序來顯示。

3.2.2 檢索所有的列

如果要檢索指定資料表的所有列,可以在SELECT子句後面使用星号

*

來實作。

在檢索一個資料表時,要注意該表所屬的模式。如果在指定表所屬的模式内部檢索資料,則可以直接使用表名;如果不在指定表所屬的模式内部檢索資料,則不但要檢視目前模式是否具有查詢的權限,而且還要在表名前面加上其所屬的模式名稱。

//SCOTT使用者下
select * from dept;

//SYSTEM使用者下
select * from scott.dept;
           

在上面的例子中,from子句的後面隻有一個資料表,實際上可以在from子句的後面指定多個資料表,每個資料表名之間使用逗号(,)分隔開,其文法格式如下:

FROM table_name1, table_name2, table_name3…table_namen
           

示例

3.2.3 檢索指定的列

使用者可以指定查詢表中的某些列而不是全部列,并且被指定列的順序不受限制,指定部分列也稱作投影操作。這些列名緊跟在SELECT關鍵字的後面,每個列名之間用逗号隔開。

其文法格式如下:

SELECT column_name1,column_name2,column_name3,column_namen
           

使用指定的列進行查詢,可以值指定要顯示的列的順序。

示例

//SCOTT使用者下
select deptno, dname, loc from dept;

//SYSTEM使用者下
select deptno, dname, loc from scott.dept;
           

3.3.4 ROWID

在Oracle資料庫中,有一個辨別行中唯一特性的行辨別符,該行辨別符的名稱為ROWID。

行辨別符ROWID是Oracle資料庫内部使用的隐藏列,由于該列實際上并不是定義在表中,是以也稱為僞列。僞列ROWID長度為18位字元,包含該行資料在Oracle資料庫中的實體位址。

使用者使用DESCRIBE指令是無法查到ROWID列的,但是可以在SELECT語句中檢索到該列。

//SCOTT使用者下
select deptno, dname, loc, rowid from dept;

//SYSTEM使用者下
select deptno, dname, loc, rowid from scott.dept;
           

3.3.5 查詢日期列

日期列是指資料類型為DATE的列。查詢日期列與查詢其他列沒有任何差別,但日期列的預設顯示格式為DD-MON-RR。

(1)以簡體中文顯示日期結果

SQL> alter session set nls_date_language= 'SIMPLIFIED CHINESE';

會話已更改。

SQL> select ename,hiredate from scott.emp;
           

顯示結果如下

ENAME      HIREDATE
---------- --------------
SMITH      17-12月-80
ALLEN      20-2月 -81
WARD       22-2月 -81
JONES      02-4月 -81
MARTIN     28-9月 -81
BLAKE      01-5月 -81
CLARK      09-6月 -81
SCOTT      19-4月 -87
KING       17-11月-81
TURNER     08-9月 -81
ADAMS      23-5月 -87

ENAME      HIREDATE
---------- --------------
JAMES      03-12月-81
FORD       03-12月-81
MILLER     23-1月 -82
           

(2)以美國英語顯示日期結果

SQL> alter session set nls_date_language= 'AMERICAN';

會話已更改。

SQL> select ename,hiredate from scott.emp;
           

顯示結果如下

ENAME      HIREDATE
---------- ------------
SMITH      17-DEC-80
ALLEN      20-FEB-81
WARD       22-FEB-81
JONES      02-APR-81
MARTIN     28-SEP-81
BLAKE      01-MAY-81
CLARK      09-JUN-81
SCOTT      19-APR-87
KING       17-NOV-81
TURNER     08-SEP-81
ADAMS      23-MAY-87

ENAME      HIREDATE
---------- ------------
JAMES      03-DEC-81
FORD       03-DEC-81
MILLER     23-JAN-82
           

(3)以特定格式顯示日期結果 不同國家地區、不同民族、不同人員都具有不同的日期使用習慣,如果希望定制日期顯示格式,并按照特定方式顯示日期格式,那麼可以設定會話的NLS_DATE_FORMAT參數。

SQL> alter session set nls_date_format= 'YYYY"年"MM"月"DD"日"';

會話已更改。

SQL> select ename,hiredate from scott.emp;
           

顯示結果

ENAME      HIREDATE
---------- --------------
SMITH      1980年12月17日
ALLEN      1981年02月20日
WARD       1981年02月22日
JONES      1981年04月02日
MARTIN     1981年09月28日
BLAKE      1981年05月01日
CLARK      1981年06月09日
SCOTT      1987年04月19日
KING       1981年11月17日
TURNER     1981年09月08日
ADAMS      1987年05月23日

ENAME      HIREDATE
---------- --------------
JAMES      1981年12月03日
FORD       1981年12月03日
MILLER     1982年01月23日
           

(4)使用TO_CHAR函數定制日期顯示函數 除了可以使用參數NLS_DATE_FORMAT設定日期顯示格式外,也可以使用TO_CHAR函數将日期值轉變為特定格式的字元串。

select ename,to_char(hiredate,'yyyy-mm-dd') from scott.emp;
select ename,to_char(hiredate,'yyyy-mm') from scott.emp;
select ename,to_char(hiredate,'mm-dd') from scott.emp;
           

3.3.6 帶有表達式的SELECT子句

在使用SELECT語句時,對于數字資料和日期資料都可以使用算術表達式。

在SELECT語句中可以使用算術運算符,包括(+)、減(-)、乘(*)、除(/)和括号。另外,在SELECT語句中不僅可以執行單獨的數學運算,還可以執行單獨的日期運算以及與列名關聯的運算。

顯示結果

SAL (SAL+1000) (SAL-1000) (SAL*1000) (SAL/1000)
---------- ---------- ---------- ---------- ----------
       800       1800       -200     800000         .8
      1600       2600        600    1600000        1.6
      1250       2250        250    1250000       1.25
      2975       3975       1975    2975000      2.975
      1250       2250        250    1250000       1.25
      2850       3850       1850    2850000       2.85
      2450       3450       1450    2450000       2.45
      3000       4000       2000    3000000          3
      5000       6000       4000    5000000          5
      1500       2500        500    1500000        1.5
      1100       2100        100    1100000        1.1

       SAL (SAL+1000) (SAL-1000) (SAL*1000) (SAL/1000)
---------- ---------- ---------- ---------- ----------
       950       1950        -50     950000        .95
      3000       4000       2000    3000000          3
      1300       2300        300    1300000        1.3
           

3.3.7 為列名指定别名值 AS 關鍵字

由于許多資料表的列名都是一些英文的縮寫,使用者為了友善檢視檢索結果,常常需要為這些列指定别名。在Oracle系統中,為列指定别名既可以使用AS關鍵字,也可以不使用任何關鍵字而直接指定。

示例

顯示結果

員工編号 員工姓名     員工工資
---------- ---------- ----------
      7369 SMITH             800
      7499 ALLEN            1600
      7521 WARD             1250
      7566 JONES            2975
      7654 MARTIN           1250
      7698 BLAKE            2850
      7782 CLARK            2450
      7788 SCOTT            3000
      7839 KING             5000
      7844 TURNER           1500
      7876 ADAMS            1100
           

在為列指定别名時,關鍵字AS是可選項,可以省略,使用者也可以在列名後面直接指定列的别名。

3.3.8 顯示不重複記錄之 DISTINCT 關鍵字

預設情況下,結果集中包含所有符合查詢條件的資料行,這樣結果集中就有可能出現重複資料。而在實際的應用中,這些重複的資料除了占據較大的顯示空間外,可能不會給使用者帶來太多有價值的東西,這樣就需要去除重複記錄,保留唯一的記錄即可。

在SELECT語句中,可以使用DISTINCT關鍵字來限制在查詢結果顯示不重複的資料,該關鍵字用在SELECT子句的清單前面。

//顯示重複記錄
select job from scott.emp;
//不顯示重複記錄
select distinct job from scott.emp;
           

顯示結果

//顯示重複記錄
JOB
---------
CLERK
SALESMAN
SALESMAN
MANAGER
SALESMAN
MANAGER
MANAGER
ANALYST
PRESIDENT
SALESMAN
CLERK
CLERK
ANALYST
CLERK
//不顯示重複記錄
JOB
---------
CLERK
SALESMAN
PRESIDENT
MANAGER
ANALYST
           

3.3.9 處理NULL值之 NVL函數 函數

NULL表示未知值,它既不是空格,也不是0。

當插入資料時,如果沒有為特定列提供資料,并且該列沒有預設值,那麼其結果為NULL。 但是在實際應用程式中,NULL顯示結果往往不能符合應用需求,在這種情況下需要使用函數NVL處理NULL,并将其轉換為合理的顯示結果。

(1)不處理NULL。

當算術表達式包含NULL時,如果不處理NULL,那麼顯示結果為空。

顯示結果

ENAME             SAL       COMM   SAL+COMM
---------- ---------- ---------- ----------
SMITH             800
ALLEN            1600        300       1900
WARD             1250        500       1750
JONES            2975
MARTIN           1250       1400       2650
BLAKE            2850
CLARK            2450
SCOTT            3000
KING             5000
TURNER           1500          0       1500
ADAMS            1100
JAMES             950
FORD             3000
MILLER           1300
           

通過顯示結果可以看出,COMM值為NULL的列,計算SAL+COMM的值也為NULL。

(2)使用NVL函數處理NULL。

如果雇員的實發工資顯示為空,那麼顯然是不符合實際情況的。為了避免出現這種情況,就應該處理NULL。

當使用函數NVL(a, b)時,如果a存在數值,則函數傳回其原有數值;如果a列為NULL,則函數傳回b。

顯示結果

ENAME             SAL       COMM       NSAL
---------- ---------- ---------- ----------
SMITH             800                   800
ALLEN            1600        300       1900
WARD             1250        500       1750
JONES            2975                  2975
MARTIN           1250       1400       2650
BLAKE            2850                  2850
CLARK            2450                  2450
SCOTT            3000                  3000
KING             5000                  5000
TURNER           1500          0       1500
ADAMS            1100                  1100
JAMES             950                   950
FORD             3000                  3000
MILLER           1300                  1300
           

當使用函數NVL(COMM,0)時,如果COMM存在數值,則函數傳回其原有數值;如果COMM列為NULL,則函數傳回0。

3.3.10 連接配接字元串之’||'操作符和CONCAT函數

當執行查詢操作時,為了顯示更有意義的結果值,有時需要将多個字元串連接配接起來。連接配接字元串可以使用“||”操作符或者CONCAT函數。

當連接配接字元串時,如果在字元串中加入數字值,那麼可以直接指定數字值;而如果在字元串中加入字元值或者日期值,那麼必須用單引号引住。

(1)使用“||”操作符連接配接字元串

ENAME||'的工作是'||JOB
-----------------------------
SMITH 的工作是 CLERK
ALLEN 的工作是 SALESMAN
WARD 的工作是 SALESMAN
JONES 的工作是 MANAGER
MARTIN 的工作是 SALESMAN
BLAKE 的工作是 MANAGER
CLARK 的工作是 MANAGER
SCOTT 的工作是 ANALYST
KING 的工作是 PRESIDENT
TURNER 的工作是 SALESMAN
ADAMS 的工作是 CLERK
JAMES 的工作是 CLERK
FORD 的工作是 ANALYST
MILLER 的工作是 CLERK
           

(2)使用函數CONCAT連接配接字元串

顯示結果

NEWNAME
------------------
THIS IS SMITH
THIS IS ALLEN
THIS IS WARD
THIS IS JONES
THIS IS MARTIN
THIS IS BLAKE
THIS IS CLARK
THIS IS SCOTT
THIS IS KING
THIS IS TURNER
THIS IS ADAMS
THIS IS JAMES
THIS IS FORD
THIS IS MILLER
           

3.3 條件查詢

3.3.1 WHERE 關鍵字

在SELECT語句中使用WHERE子句可以實作對資料行的篩選操作,隻有滿足WHERE子句中判斷條件的行才會顯示在結果集中,而那些不滿足WHERE子句判斷條件的行則不包括在結果集中。

這種篩選操作是非常有意義的,通過篩選資料,可以從大量的資料中得到使用者所需要的資料。

在SELECT語句中,WHERE子句位于FROM子句之後,其文法格式如下:

SELECT columns_list
  FROM table_name
 WHERE conditional_expression
           
  • columns_list:字段清單。  table_name:表名。
  • conditional_expression:篩選條件表達式。

3.3.2 比較篩選條件

可以在WHERE子句中使用比較運算符來篩選資料,這樣隻有滿足篩選條件的資料行才會被檢索出來,不滿足比較條件的資料行則不會被檢索出來。

基本的“比較篩選”操作主要有以下6種情況:

  • A = B:比較A與B是否相等。
  • A ! B或A <> B:比較A與B是否不相等。
  • A > B:比較A是否大于B。
  • A < B:比較A是否小于B。
  • A >= B:比較A是否大于或等于B。
  • A <= B:比較A是否小于或等于B。

另外,除了基本的“比較篩選”操作外,還有以下兩個特殊的“比較篩選”操作。

  • A {operator} ANY (B):表示A與B中的任何一個元素進行operator運算符的比較,隻要有一個比較值為true,就傳回資料行。
  • A = {operator} ALL (B):表示A與B中的所有元素進行operator運算符的比較,隻有與所有元素比較值都為true,才傳回資料行。

3.3.3 模糊查詢之 LIKE 關鍵字

模糊查詢可以查找相關的資料,模糊查詢使用LIKE關鍵字,一般要配合通配符

_

或者

%

使用

  • _

    通配符:一個

    _

    表示一個占位
  • %

    通配符:一個

    %

    可以表示多個占位符

示例

//查詢ename以SYS開頭,後面隻跟有一個字元的相關資料
select empno, ename, sal from emp where ename like 'SYS_';
//查詢ename以SYS開頭,後面跟有兩個字元的相關資料
select empno, ename, sal from emp where ename like 'SYS__';
//查詢ename以SYS開頭,且前後都隻有一個字元的相關資料
select empno, ename, sal from emp where ename like '_SYS_';
//查詢ename以SYS開頭的所有相關資料
select empno, ename, sal from emp where ename like 'SYS%';
//查詢ename包含SYS的相關資料
select empno, ename, sal from emp where ename like '%SYS%';
//查詢ename包含SYS,且前面隻有一個字元的相關資料
select empno, ename, sal from emp where ename like '_SYS%';
           

注意:

要查詢的字元串中含有“%”或“_”時,可以使用轉義(escape)關鍵字(字元

\

)實作查詢。

3.3.4 AND 關鍵字

AND邏輯運算符表示兩個邏輯表達式之間“邏輯與”的關系,使用者完全可以使用AND運算符加比較運算符來代替BETWEEN…AND關鍵字。

select empno, ename, sal from emp where sal < 1300 and sal > 3000;
select empno, ename, sal from emp where sal > 13000 and sal < 3000;
           

3.3.5 OR關鍵字

OR邏輯運算符表示兩個邏輯表達式之間“邏輯或”的關系,兩個表達式的結果中有一個為true,則這個邏輯或表達式的值就為true。

3.3.6 NOT 關鍵字

NOT邏輯運算符對表達式執行邏輯非的運算。

3.3.7 BETWEEN 關鍵字

需要傳回某一個資料值是否位于兩個給定的值之間,可以使用範圍條件進行檢索。通常使用BETWEEN…AND和NOT…BETWEEN…AND來指定範圍條件。

使用BETWEEN…AND查詢條件時,指定的第一個值必須小于第二個值。因為BETWEEN…AND實質是查詢條件“大于等于第一個值,并且小于等于第二個值”的簡寫形式,即BETWEEN…AND要包括兩端的值,等價于比較運算符(>=…<=)。

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

3.3.8 IN 關鍵字

當測試一個資料值是否比對一組目标值中的一個時,通常使用IN關鍵字來指定清單搜尋條件。

IN關鍵字的格式是IN(目标值1,目标值2,目标值3,…),目标值的項目之間必須使用逗号分隔,并且括在括号中。

另外,NOT IN表示查詢指定的值不在某一組目标值中,這種方式在實際應用中也很常見。

3.3.9 IS NULL 和 IS NOT NULL 關鍵字

空值(NULL)從技術上來說就是未知的、不确定的值,但空值與空字元串不同,因為空值是不存在的值,而空字元串是長度為0的字元串。

因為空值代表的是未知的值,是以并不是所有的空值都相等。例如,student表中有兩個學生的年齡未知,但無法證明這兩個學生的年齡相等。這樣就不能用“=”運算符來檢測空值。是以SQL引入了一個IS NULL關鍵字來檢測特殊值之間的等價性,并且IS NULL關鍵字通常在WHERE子句中使用。

select empno, ename, sal, comm from emp where comm is null;
select empno, ename, sal, comm from emp where comm is not null;
           

當與NULL進行比較時,不要使用等于(=)、不等于(<>)操作符。盡管使用它們不會有任何文法錯誤,但條件總是FALSE。

select ename, mgr from emp where mgr is null;
select ename, mgr from emp where mgr = null;
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

3.4 分組查詢

3.4.1 分組查詢介紹

資料分組的目的是用來彙總資料或為整個分組顯示單行的彙總資訊,通常在查詢結果集中使用GROUP BY子句對記錄進行分組。

在SELECT語句中,GROUP BY子句位于FROM子句之後,其文法格式如下:

SELECT columns_list
  FROM table_name
[WHERE conditional_expression]
GROUP BY columns_list
           
  • columns_list:字段清單,在GROUP BY子句中也可以指定多個列分組。  table_name:表名。
  • conditional_expression:篩選條件表達式。
  • GROUP BY子句可以基于指定某一列的值将資料集合劃分為多個分組,同一組内所有記錄在分組屬性上具有相同值,也可以基于指定多列的值将資料集合劃分為多個分組。

**3.4.2 使用GROUP BY進行單列分組 **

單列分組是指基于列生成分組統計結果,當進行單列分組時,會基于分組列的每個不同值生成一個統計結果。

GROUP BY子句經常與聚集函數一起使用。使用GROUP BY子句和聚集函數,可以實作對查詢結果中每一組資料進行分類統計。是以,在結果中每組資料都有一個與之對應的統計值。在Oracle系統中,經常使用的統計函數如圖所示。

Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

查詢結果

JOB                  SUM(SAL)
------------------ ----------
CLERK                    4150
SALESMAN                 5600
PRESIDENT                5000
MANAGER                  8275
ANALYST                  6000
           

在使用GROUP BY子句時,要注意:

  • SELECT子句的後面隻可以有兩類表達式:統計函數和進行分組的列名。
  • 在SELECT子句中的列名必須是進行分組的列,除此之外添加其他的列名都是錯誤的,但是GROUP BY子句後面的列名可以不出現在SELECT子句中。
  • 在預設情況下,将按照GROUP BY子句指定的分組列升序排列,如果需要重新排序,可以使用ORDER BY子句指定新的排列順序。

GROUP BY子句中的列可以不在SELECT清單中。

查詢結果

SUM(SAL)
----------
      4150
      5600
      5000
      8275
      6000
           

3.4.3 使用GROUP BY進行多列分組

多列分組是指基于兩個或兩個以上的列生成分組統計結果。當進行多列分組時,會基于多個列的不同值生成統計結果。

3.4.4 使用ORDER BY改變分組排序結果

當使用GROUP BY子句執行分組統計時,會自動基于分組列進行升序排列。為了改變分組資料的排序結果,需要使用ORDER BY子句。

3.4.5 使用HAVING子句限制分組結果

HAVING子句通常與GROUP BY子句一起使用,在完成對分組結果統計後,可以使用HAVING子句對分組的結果做進一步的篩選。

如果不使用GROUP BY子句,HAVING子句的功能與WHERE子句一樣。HAVING子句和WHERE子句的相似之處都是定義搜尋條件,唯一不同的是HAVING子句中可以包含聚合函數,如常用的(count)、(avg)、(sum)等,在WHERE子句中則不可以使用聚合函數。

  • 如果在SELECT語句中使用了GROUP BY子句,那麼HAVING子句将應用于GROUP BY子句建立的那些組。
  • 如果指定了WHERE子句,而沒有指定GROUP BY子句,那麼HAVING子句将應用于WHERE子句的輸出,并且整個輸出被看作一個組.
  • 如果在SELECT語句中既沒有指定WHERE子句,也沒有指定GROUP BY子句,那麼HAVING子句将應用于FROM子句的輸出,并且将其看作一個組。
select deptno as  部門編号,
       avg(sal) as  平均工資 
  from emp 
group by deptno 
having avg(sal) > 2000 ;
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

上面的示例無法使用WHERE子句直接過濾出平均工資大于2000的部門資訊,因為在WHERE子句中不可以使用聚合函數(這裡是AVG)。

通常情況下,HAVING子句與GROUP BY子句一起使用,這樣可以彙總相關資料後再進一步篩選彙總的資料。

3.4.6 在GROUP BY中使用ROLLUP和CUBE操作符

預設情況下,當使用GROUP BY子句生成資料統計結果時,隻會生成相關列的資料統計資訊,而不會生成小計和總計統計。

在實際應用程式中,不僅需要獲得以上統計結果,而且可能還需要取得橫向、縱向小計統計以及總計統計,例如部門的平均工資、崗位的平均工資、所有雇員的平均工資等。為了取得更全面的資料統計,可以使用ROLLUP和CUBE操作符。

(1)使用ROLLUP操作符執行資料統計

當使用ROLLUP操作符時,在保留原有統計結果的基礎上,還會生成橫向小計和總計。

select deptno as  部門編号, 
	   job as  崗位, 
	   avg(sal) as  平均工資
  from emp 
group by rollup(deptno,job) ;
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

(2)使用CUBE操作符執行資料統計

當使用CUBE操作符時,在保留原有統計結果的基礎上,還會生成橫向小計、縱向小計崗位平均工資和總計。

select deptno as  部門編号, 
	   job as  崗位, 
	   avg(sal) as  平均工資
  from emp 
group by cube(deptno,job) ;
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

(3)使用GROUPING函數

當使用ROLLUP或者CUBE操作符生成統計結果時,某個統計結果行可能用到一列或者多列,也可能沒有使用任何列。為了确定統計結果是否使用了特定列,可以使用GROUPING函數。如果該函數傳回0,則表示統計結果使用了該列;如果函數傳回1,則表示統計結果沒有使用該列。

select deptno,job, sum (sal),grouping(deptno),grouping(job)
  from emp 
group by rollup(deptno,job) ;
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

(4)在ROLLUP操作符中使用複合列

複合列被看作一個邏輯單元的列組合,當引用複合列時,需要用括号包覆相關列。通過在ROLLUP操作符中使用複合列,可以略過ROLLUP操作符的某些統計結果。

例如,子句GROUP BY ROLLUP(a,b,c)的統計結果等同于GROUP BY(a,b,c)、GROUP BY(a,b)、GROUP BY a以及GROUP BY ( )的并集;而如果将(b,c)作為複合列,那麼子句GROUP BY ROLLUP(a,(b,c))的結果等同于GROUP BY(a,b,c)、GROUP BY a以及GROUP BY ()的并集。

select deptno,job, sum (sal)
  from emp 
group by rollup((deptno,job)) ;
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

6.使用GROUPING SETS操作符

GROUPING SETS操作符是GROUP BY子句的進一步擴充。在Oracle Database 9i之前,使用GROUP BY子句一次隻能顯示單種分組結果,如果要生成多種分組統計結果,那麼需要編寫多條SELECT分組語句。從Oracle Database 9i開始,通過使用GROUPING SETS操作符,可以合并多個分組的統計結果,進而簡化了多個分組操作。

select deptno, job, avg (sal)  
  from emp 
group by grouping sets(deptno,job);
           
Oracle 資料庫(六)—— Oracle SQL語言之使用者模式、簡單查詢、條件查詢、分組查詢和排序查詢一、SQL 語言概述二、使用者模式三、基本查詢

3.5 排序查詢

3.5.1 排序查詢介紹

在檢索資料時,如果把資料從資料庫中直接讀取出來,這時查詢結果将按照預設順序排列,但往往這種預設排列順序并不是使用者所需要的。尤其傳回資料量較大時,使用者檢視自己想要的資訊非常不友善,是以需要對檢索的結果集進行排序。

在SELECT語句中,可以使用ORDER BY子句對檢索的結果集進行排序,該子句位于FROM子句之後,其文法格式如下:

SELECT columns_list
  FROM table_name
[WHERE conditional_expression]
[GROUP BY columns_list]
ORDER BY {order_by_expression [ ASC | DESC ]} [ ,...n ]
           
  • columns_list:字段清單,在GROUP BY子句中也可以指定多個列分組。
  • table_name:表名。
  • conditional_expression:篩選條件表達式。
  • order_by_expression:表示要排序的列名或表達式。
  • 關鍵字ASC表示按升序排列,這也是預設的排序方式;
  • 關鍵字DESC表示按降序排列。

ORDER BY子句可以根據查詢結果中的一個列或多個列對查詢結果進行排序,并且第一個排序項是主要的排序依據,其他的是次要的排序依據。

3.5.2 單列排序

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

還可以在ORDER BY子句中使用列号。當執行排序操作時,不僅可以按照列名、列别名進行排序,也可以按照列或表達式在選擇清單中的位置進行排序。如果列名或表達式名稱很長,那麼使用列位号排序可以縮減排序語句長度。

另外,當使用UNION、UNION ALL、INTERSECT、MINUS等集合操作符合并查詢結果時,如果選擇清單的列名不同,并且希望進行排序,則必須使用列位置進行排序。

但是在SQL語句中應該盡可能地不使用ORDER BY子句的上述用法,因為這種用法的易讀性實在太差了。在不少有關Oracle SQL的書中根本就沒有介紹ORDER BY子句的這種用法。盡管如此,當使用UNION、UNION ALL、INTERSECT、MINUS等集合操作符合并查詢結果時,或者為了減少輸入,特别是當放在ORDER BY子句之後的列名或表達式很長時,還是可以使用此種用法。

可以使用非選擇清單列排序。當執行排序操作時,多數情況都會選擇清單中的列執行排序操作,以便于更直覺地顯示資料。但是在執行排序操作時,排序列也可以不是選擇清單中的列。

3.5.3 多列排序

當執行排序操作時,不僅可以基于單列進行排序,也可以基于多列進行排序。當以多列進行排序時,首先按照第一列進行排序,當第一列存在相同資料時,再以第二列進行排序,以此類推。

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

           

參考文獻:

  1. Oracle 11g從入門到精通 第二版,明日科技 著,清華大學出版社有限公司