SQL 快速指南



SQL - 概述

SQL 是一種操作資料庫的語言;它包括資料庫建立、刪除、獲取行、修改行等。SQL 是 **ANSI**(美國國家標準學會)標準語言,但 SQL 語言有很多不同的版本。

什麼是 SQL?

SQL 是結構化查詢語言,它是一種用於儲存、操作和檢索儲存在關係資料庫中的資料的計算機語言。

SQL 是關係資料庫系統的標準語言。所有關係資料庫管理系統 (RDMS),例如 MySQL、MS Access、Oracle、Sybase、Informix、Postgres 和 SQL Server 都使用 SQL 作為其標準資料庫語言。

此外,它們還使用不同的方言,例如:

  • MS SQL Server 使用 T-SQL,
  • Oracle 使用 PL/SQL,
  • MS Access 的 SQL 版本稱為 JET SQL(本機格式)等。

為什麼要使用 SQL?

SQL 非常流行,因為它提供了以下優勢:

  • 允許使用者訪問關係資料庫管理系統中的資料。

  • 允許使用者描述資料。

  • 允許使用者定義資料庫中的資料並操作該資料。

  • 允許使用 SQL 模組、庫和預編譯器嵌入到其他語言中。

  • 允許使用者建立和刪除資料庫和表。

  • 允許使用者在資料庫中建立檢視、儲存過程和函式。

  • 允許使用者設定表、過程和檢視的許可權。

SQL 簡史

  • **1970** 年 - IBM 的 Edgar F. "Ted" Codd 博士被稱為關係資料庫之父。他描述了資料庫的關係模型。

  • **1974** 年 - 結構化查詢語言出現。

  • **1978** 年 - IBM 致力於開發 Codd 的想法併發布了一個名為 System/R 的產品。

  • **1986** 年 - IBM 開發了關係資料庫的第一個原型,並由 ANSI 標準化。第一個關係資料庫由 Relational Software 釋出,後來被稱為 Oracle。

SQL 過程

當您為任何 RDBMS 執行 SQL 命令時,系統會確定執行您的請求的最佳方法,SQL 引擎會確定如何解釋該任務。

此過程中包含各種元件。

這些元件包括:

  • 查詢排程程式
  • 最佳化引擎
  • 經典查詢引擎
  • SQL 查詢引擎等。

經典查詢引擎處理所有非 SQL 查詢,但 SQL 查詢引擎不會處理邏輯檔案。

下圖顯示了 SQL 架構的簡單示意圖:

SQL Architecture

SQL 命令

與關係資料庫互動的標準 SQL 命令為 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。根據其性質,這些命令可以分為以下幾組:

DDL - 資料定義語言

序號 命令和描述
1

CREATE

建立資料庫中的新表、表的檢視或其他物件。

2

ALTER

修改現有資料庫物件,例如表。

3

DROP

刪除資料庫中的整個表、表的檢視或其他物件。

DML - 資料操縱語言

序號 命令和描述
1

SELECT

從一個或多個表中檢索某些記錄。

2

INSERT

建立記錄。

3

UPDATE

修改記錄。

4

DELETE

刪除記錄。

DCL - 資料控制語言

序號 命令和描述
1

GRANT

授予使用者許可權。

2

REVOKE

收回授予使用者的許可權。

SQL - RDBMS 概念

什麼是 RDBMS?

RDBMS 代表 ****系 ****據 **** ****理 ****統。RDBMS 是 SQL 和所有現代資料庫系統(如 MS SQL Server、IBM DB2、Oracle、MySQL 和 Microsoft Access)的基礎。

關係資料庫管理系統 (RDBMS) 是一種基於 E. F. Codd 引入的關係模型的資料庫管理系統 (DBMS)。

什麼是表?

RDBMS 中的資料儲存在稱為 **表** 的資料庫物件中。該表基本上是相關資料條目的集合,它包含許多列和行。

請記住,表是關係資料庫中最常見和最簡單的儲存資料形式。以下程式是 CUSTOMERS 表的示例:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

什麼是欄位?

每個表都細分為稱為欄位的較小實體。CUSTOMERS 表中的欄位包括 ID、NAME、AGE、ADDRESS 和 SALARY。

欄位是表中的一列,旨在維護有關表中每個記錄的特定資訊。

什麼是記錄或行?

記錄也稱為資料行,是表中存在的每個單獨條目。例如,上面的 CUSTOMERS 表中有 7 條記錄。以下是 CUSTOMERS 表中的一行資料或記錄:

+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

記錄是表中的水平實體。

什麼是列?

列是表中的垂直實體,包含與表中特定欄位關聯的所有資訊。

例如,CUSTOMERS 表中的一列是 ADDRESS,它表示位置描述,如下所示:

+-----------+
| ADDRESS   |
+-----------+
| Ahmedabad |
| Delhi     |
| Kota      |
| Mumbai    |
| Bhopal    |
| MP        |
| Indore    |
+----+------+

什麼是 NULL 值?

表中的 NULL 值是欄位中看起來為空白的值,這意味著具有 NULL 值的欄位是沒有任何值的欄位。

理解 NULL 值與零值或包含空格的欄位不同非常重要。具有 NULL 值的欄位是在建立記錄時留空的欄位。

SQL 約束

約束是在表上資料列上實施的規則。它們用於限制可以進入表的的資料型別。這確保了資料庫中資料的準確性和可靠性。

約束可以是列級或表級。列級約束僅應用於一列,而表級約束應用於整個表。

以下是 SQL 中一些最常用的約束:

  • NOT NULL 約束 - 確保列不能具有 NULL 值。

  • UNIQUE 約束 - 確保列中的所有值都不同。

  • 主鍵 - 唯一標識資料庫表中的每一行/記錄。

  • 外部索引鍵 - 唯一標識任何其他資料庫表中的每一行/記錄。

  • 索引 - 用於非常快速地建立和檢索資料庫中的資料。

資料完整性

每個 RDBMS 都存在以下類別的資料完整性:

  • 實體完整性 - 表中沒有重複行。

  • 域完整性 - 透過限制值的型別、格式或範圍,強制執行給定列的有效條目。

  • 參照完整性 - 不能刪除被其他記錄引用的行。

  • 使用者定義完整性 - 強制執行一些不屬於實體、域或參照完整性的特定業務規則。

資料庫規範化

資料庫規範化是有效組織資料庫中資料的過程。此規範化過程有兩個原因 -

  • 消除冗餘資料,例如,在多個表中儲存相同的資料。

  • 確保資料依賴關係合理。

這兩個原因都是值得追求的目標,因為它們減少了資料庫佔用的空間並確保資料以邏輯方式儲存。規範化包括一系列指導原則,可幫助您建立良好的資料庫結構。

規範化指導原則分為正規化;可以將正規化視為資料庫結構的格式或佈局方式。正規化的目標是組織資料庫結構,使其符合第一正規化、第二正規化和最終第三正規化的規則。

您可以選擇進一步進行,進入第四正規化、第五正規化等,但通常,第三正規化已經足夠了。

SQL - RDBMS 資料庫

有很多流行的 RDBMS 可供使用。本教程簡要概述了一些最流行的 RDBMS。這將幫助您比較它們的基本功能。

MySQL

MySQL 是一個開源的 SQL 資料庫,由一家瑞典公司 MySQL AB 開發。MySQL 發音為“my ess-que-ell”,與 SQL 的發音“sequel”形成對比。

MySQL 支援許多不同的平臺,包括 Microsoft Windows、主要的 Linux 發行版、UNIX 和 Mac OS X。

MySQL 具有免費版和付費版,具體取決於其用途(非商業/商業)和功能。MySQL 帶有一個非常快速、多執行緒、多使用者且健壯的 SQL 資料庫伺服器。

歷史

  • Michael Widenius 和 David Axmark 從 1994 年開始開發 MySQL。

  • 1995 年 5 月 23 日首次內部發布。

  • 1998 年 1 月 8 日釋出了 Windows 版本,適用於 Windows 95 和 NT。

  • 版本 3.23:2000 年 6 月釋出測試版,2001 年 1 月釋出正式版。

  • 版本 4.0:2002 年 8 月釋出測試版,2003 年 3 月釋出正式版(聯合體)。

  • 版本 4.1:2004 年 6 月釋出測試版,2004 年 10 月釋出正式版。

  • 版本 5.0:2005 年 3 月釋出測試版,2005 年 10 月釋出正式版。

  • 2008 年 2 月 26 日,Sun Microsystems 收購了 MySQL AB。

  • 版本 5.1:2008 年 11 月 27 日釋出正式版。

功能

  • 高效能。
  • 高可用性。
  • 可擴充套件性和靈活性 執行任何內容。
  • 強大的事務支援。
  • Web 和資料倉庫優勢。
  • 強大的資料保護。
  • 全面的應用程式開發。
  • 易於管理。
  • 開源自由和 24x7 支援。
  • 最低的總擁有成本。

MS SQL Server

MS SQL Server 是由 Microsoft Inc. 開發的關係資料庫管理系統。其主要查詢語言為 -

  • T-SQL
  • ANSI SQL

歷史

  • 1987 年 - Sybase 釋出適用於 UNIX 的 SQL Server。

  • 1988 年 - Microsoft、Sybase 和 Aston-Tate 將 SQL Server 移植到 OS/2。

  • 1989 年 - Microsoft、Sybase 和 Aston-Tate 釋出適用於 OS/2 的 SQL Server 1.0。

  • 1990 年 - 釋出 SQL Server 1.1,支援 Windows 3.0 客戶端。

  • Aston-Tate 退出 SQL Server 開發。

  • 2000 年 - Microsoft 釋出 SQL Server 2000。

  • 2001 年 - Microsoft 釋出適用於 SQL Server Web 版本 1 的 XML(下載)。

  • 2002 年 - Microsoft 釋出 SQLXML 2.0(從適用於 SQL Server 的 XML 重新命名)。

  • 2002 年 - Microsoft 釋出 SQLXML 3.0。

  • 2005 年 - Microsoft 於 2005 年 11 月 7 日釋出 SQL Server 2005。

功能

  • 高效能
  • 高可用性
  • 資料庫映象
  • 資料庫快照
  • CLR 整合
  • 服務代理
  • DDL 觸發器
  • 排名函式
  • 基於行版本的隔離級別
  • XML 整合
  • TRY...CATCH
  • 資料庫郵件

ORACLE

它是一個非常大型的多使用者資料庫管理系統。Oracle 是由 Oracle Corporation 開發的關係資料庫管理系統。

Oracle 致力於有效地管理其資源,即網路中多個請求和傳送資料的客戶端之間的資訊資料庫。

它是客戶端/伺服器計算的絕佳資料庫伺服器選擇。Oracle 支援客戶端和伺服器的所有主要作業系統,包括 MSDOS、NetWare、UnixWare、OS/2 和大多數 UNIX 版本。

歷史

Oracle 成立於 1977 年,在業界慶祝其 32 週年(從 1977 年到 2009 年)。

  • 1977 年 - Larry Ellison、Bob Miner 和 Ed Oates 成立了軟體開發實驗室以開展開發工作。

  • 1979 年 - 釋出了 Oracle 2.0 版本,它成為第一個商業關係資料庫和第一個 SQL 資料庫。公司更名為 Relational Software Inc. (RSI)。

  • 1981 年 - RSI 開始為 Oracle 開發工具。

  • 1982 年 - RSI 更名為 Oracle Corporation。

  • 1983 年 - Oracle 釋出了 3.0 版本,該版本用 C 語言重寫並在多個平臺上執行。

  • 1984 年 - 釋出了 Oracle 4.0 版本。它包含併發控制等功能 - 多版本讀一致性等。

  • 1985 年 - 釋出了 Oracle 4.0 版本。它包含併發控制等功能 - 多版本讀一致性等。

  • 2007 年 - Oracle 釋出了 Oracle11g。新版本側重於更好的分割槽、輕鬆遷移等。

功能

  • 併發
  • 讀取一致性
  • 鎖定機制
  • 使資料庫處於靜止狀態
  • 可移植性
  • 自管理資料庫
  • SQL*Plus
  • ASM
  • 排程程式
  • 資源管理器
  • 資料倉庫
  • 物化檢視
  • 點陣圖索引
  • 表壓縮
  • 並行執行
  • 分析 SQL
  • 資料探勘
  • 分割槽

MS ACCESS

這是 Microsoft 最受歡迎的產品之一。Microsoft Access 是一款入門級資料庫管理軟體。MS Access 資料庫不僅價格低廉,而且對於小型專案來說也是一個功能強大的資料庫。

MS Access 使用 Jet 資料庫引擎,該引擎使用特定的 SQL 語言方言(有時稱為 Jet SQL)。

MS Access 附帶 MS Office 套件的專業版。MS Access 具有易於使用的直觀圖形介面。

  • 1992 年 - 釋出 Access 1.0 版本。

  • 1993 年 - 釋出 Access 1.1 版本,以提高與包含 Access Basic 程式語言的相容性。

  • 最重大的轉變是從 Access 97 到 Access 2000。

  • 2007 年 - Access 2007 引入了一種新的資料庫格式 ACCDB,它支援複雜的資料型別,例如多值和附件欄位。

功能

  • 使用者可以建立表、查詢、窗體和報表,並使用宏將它們連線在一起。

  • 可以選擇將資料匯入和匯出到許多格式,包括 Excel、Outlook、ASCII、dBase、Paradox、FoxPro、SQL Server、Oracle、ODBC 等。

  • 還有 Jet 資料庫格式(Access 2007 中的 MDB 或 ACCDB),它可以將應用程式和資料包含在一個檔案中。這使得將整個應用程式分發給其他使用者非常方便,他們可以在斷開連線的環境中執行它。

  • Microsoft Access 提供引數化查詢。這些查詢和 Access 表可以從其他程式(如 VB6 和 .NET)透過 DAO 或 ADO 進行引用。

  • Microsoft SQL Server 的桌面版可以用作 Jet 資料庫引擎的替代方案。

  • Microsoft Access 是一個基於檔案伺服器的資料庫。與客戶端-伺服器關係資料庫管理系統 (RDBMS) 不同,Microsoft Access 不實現資料庫觸發器、儲存過程或事務日誌記錄。

SQL - 語法

SQL 後跟一組獨特的規則和指南,稱為語法。本教程透過列出所有基本 SQL 語法,使您快速入門 SQL。

所有 SQL 語句都以 SELECT、INSERT、UPDATE、DELETE、ALTER、DROP、CREATE、USE、SHOW 等任何關鍵字開頭,並且所有語句都以分號 (;) 結尾。

這裡需要注意的最重要的一點是 SQL 不區分大小寫,這意味著 SELECT 和 select 在 SQL 語句中具有相同的含義。而 MySQL 會區分表名。因此,如果您使用的是 MySQL,則需要按資料庫中存在的名稱提供表名。

SQL 中的各種語法

本教程中提供的所有示例均已在 MySQL 伺服器上進行了測試。

SQL SELECT 語句

SELECT column1, column2....columnN
FROM   table_name;

SQL DISTINCT 子句

SELECT DISTINCT column1, column2....columnN
FROM   table_name;

SQL WHERE 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION;

SQL AND/OR 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION-1 {AND|OR} CONDITION-2;

SQL IN 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name IN (val-1, val-2,...val-N);

SQL BETWEEN 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name BETWEEN val-1 AND val-2;

SQL LIKE 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name LIKE { PATTERN };

SQL ORDER BY 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION
ORDER BY column_name {ASC|DESC};

SQL GROUP BY 子句

SELECT SUM(column_name)
FROM   table_name
WHERE  CONDITION
GROUP BY column_name;

SQL COUNT 子句

SELECT COUNT(column_name)
FROM   table_name
WHERE  CONDITION;

SQL HAVING 子句

SELECT SUM(column_name)
FROM   table_name
WHERE  CONDITION
GROUP BY column_name
HAVING (arithematic function condition);

SQL CREATE TABLE 語句

CREATE TABLE table_name(
column1 datatype,
column2 datatype,
column3 datatype,
.....
columnN datatype,
PRIMARY KEY( one or more columns )
);

SQL DROP TABLE 語句

DROP TABLE table_name;

SQL CREATE INDEX 語句

CREATE UNIQUE INDEX index_name
ON table_name ( column1, column2,...columnN);

SQL DROP INDEX 語句

ALTER TABLE table_name
DROP INDEX index_name;

SQL DESC 語句

DESC table_name;

SQL TRUNCATE TABLE 語句

TRUNCATE TABLE table_name;

SQL ALTER TABLE 語句

ALTER TABLE table_name {ADD|DROP|MODIFY} column_name {data_ype};

SQL ALTER TABLE 語句(重新命名)

ALTER TABLE table_name RENAME TO new_table_name;

SQL INSERT INTO 語句

INSERT INTO table_name( column1, column2....columnN)
VALUES ( value1, value2....valueN);

SQL UPDATE 語句

UPDATE table_name
SET column1 = value1, column2 = value2....columnN=valueN
[ WHERE  CONDITION ];

SQL DELETE 語句

DELETE FROM table_name
WHERE  {CONDITION};

SQL CREATE DATABASE 語句

CREATE DATABASE database_name;

SQL DROP DATABASE 語句

DROP DATABASE database_name;

SQL USE 語句

USE database_name;

SQL COMMIT 語句

COMMIT;

SQL ROLLBACK 語句

ROLLBACK;

SQL - 資料型別

SQL 資料型別是指定任何物件資料型別的屬性。每個列、變數和表示式在 SQL 中都有一個相關的資料型別。在建立表時可以使用這些資料型別。您可以根據需要為表列選擇資料型別。

SQL Server 提供六類資料型別供您使用,如下所示 -

精確數值資料型別

資料型別
bigint -9,223,372,036,854,775,808 9,223,372,036,854,775,807
int -2,147,483,648 2,147,483,647
smallint -32,768 32,767
tinyint 0 255
bit 0 1
decimal -10^38 +1 10^38 -1
numeric -10^38 +1 10^38 -1
money -922,337,203,685,477.5808 +922,337,203,685,477.5807
smallmoney -214,748.3648 +214,748.3647

近似數值資料型別

資料型別
float -1.79E + 308 1.79E + 308
real -3.40E + 38 3.40E + 38

日期和時間資料型別

資料型別
datetime 1753 年 1 月 1 日 9999 年 12 月 31 日
smalldatetime 1900 年 1 月 1 日 2079 年 6 月 6 日
date 儲存日期,例如 1991 年 6 月 30 日
time

儲存一天中的時間,例如 12:30 PM。

注意 − 在這裡,datetime 的精度為 3.33 毫秒,而 smalldatetime 的精度為 1 分鐘。

字元字串資料型別

序號 資料型別和描述
1

char

最大長度為 8,000 個字元。(固定長度非 Unicode 字元)

2

varchar

最大 8,000 個字元。(可變長度非 Unicode 資料)。

3

varchar(max)

最大長度為 2E + 31 個字元,可變長度非 Unicode 資料(僅限 SQL Server 2005)。

4

text

可變長度非 Unicode 資料,最大長度為 2,147,483,647 個字元。

Unicode 字串資料型別

序號 資料型別和描述
1

nchar

最大長度為 4,000 個字元。(固定長度 Unicode)

2

nvarchar

最大長度為 4,000 個字元。(可變長度 Unicode)

3

nvarchar(max)

最大長度為 2E + 31 個字元(僅限 SQL Server 2005)。(可變長度 Unicode)

4

ntext

最大長度為 1,073,741,823 個字元。(可變長度 Unicode)

二進位制資料型別

序號 資料型別和描述
1

binary

最大長度為 8,000 位元組(固定長度二進位制資料)

2

varbinary

最大長度為 8,000 位元組。(可變長度二進位制資料)

3

varbinary(max)

最大長度為 2E + 31 位元組(僅限 SQL Server 2005)。(可變長度二進位制資料)

4

image

最大長度為 2,147,483,647 位元組。(可變長度二進位制資料)

其他資料型別

序號 資料型別和描述
1

sql_variant

儲存各種 SQL Server 支援的資料型別的值,除了 text、ntext 和 timestamp。

2

timestamp

儲存資料庫範圍內的唯一編號,每當更新一行時都會更新該編號

3

uniqueidentifier

儲存全域性唯一識別符號 (GUID)

4

xml

儲存 XML 資料。您可以將 xml 例項儲存在列或變數中(僅限 SQL Server 2005)。

5

cursor

對遊標物件的引用

6

table

儲存結果集以供以後處理

SQL - 運算子

什麼是 SQL 中的運算子?

運算子是保留字或字元,主要用於 SQL 語句的 WHERE 子句中執行操作(例如比較和算術運算)。這些運算子用於在 SQL 語句中指定條件,並用作語句中多個條件的連線詞。

  • 算術運算子
  • 比較運算子
  • 邏輯運算子
  • 用於否定條件的運算子

SQL 算術運算子

假設“變數 a”持有 10,“變數 b”持有 20,則 -

顯示示例

運算子 描述 示例
+(加法) 將運算子兩側的值相加。 a + b 將得到 30
-(減法) 從左運算元中減去右運算元。 a - b 將得到 -10
*(乘法) 將運算子兩側的值相乘。 a * b 將得到 200
/(除法) 將左運算元除以右運算元。 b / a 將得到 2
%(模數) 將左運算元除以右運算元並返回餘數。 b % a 將得到 0

SQL 比較運算子

假設“變數 a”持有 10,“變數 b”持有 20,則 -

顯示示例

運算子 描述 示例
= 檢查兩個運算元的值是否相等,如果相等則條件為真。 (a = b)不為真。
!= 檢查兩個運算元的值是否相等,如果不相等則條件為真。 (a != b)為真。
<> 檢查兩個運算元的值是否相等,如果不相等則條件為真。 (a <> b)為真。
> 檢查左運算元的值是否大於右運算元的值,如果大於則條件為真。 (a > b)不為真。
< 檢查左運算元的值是否小於右運算元的值,如果小於則條件為真。 (a < b)為真。
>= 檢查左運算元的值是否大於或等於右運算元的值,如果大於或等於則條件為真。 (a >= b)不為真。
<= 檢查左運算元的值是否小於或等於右運算元的值,如果小於或等於則條件為真。 (a <= b)為真。
!< 檢查左運算元的值是否不小於右運算元的值,如果滿足則條件為真。 (a !< b)為假。
!> 檢查左運算元的值是否不大於右運算元的值,如果滿足則條件為真。 (a !> b)為真。

SQL 邏輯運算子

以下是 SQL 中所有可用邏輯運算子的列表。

顯示示例

序號 運算子和描述
1

ALL

ALL 運算子用於將值與另一個值集中所有值進行比較。

2

AND

AND 運算子允許 SQL 語句的 WHERE 子句中存在多個條件。

3

ANY

ANY 運算子用於將值與列表中任何適用的值進行比較,具體取決於條件。

4

BETWEEN

BETWEEN 運算子用於搜尋在給定最小值和最大值的一組值內的值。

5

EXISTS

EXISTS 運算子用於搜尋指定表中是否存在滿足特定條件的行。

6

IN

IN 運算子用於將值與已指定的文字值列表進行比較。

7

LIKE

LIKE 運算子用於使用萬用字元運算子將值與類似的值進行比較。

8

NOT

NOT 運算子反轉與其一起使用的邏輯運算子的含義。例如:NOT EXISTS、NOT BETWEEN、NOT IN 等。這是一個否定運算子。

9

OR

OR 運算子用於組合 SQL 語句的 WHERE 子句中的多個條件。

10

IS NULL

NULL 運算子用於將值與 NULL 值進行比較。

11

UNIQUE

UNIQUE 運算子搜尋指定表中的每一行以確保唯一性(無重複)。

SQL - 表示式

表示式是結合了一個或多個值、運算子和 SQL 函式,並計算出一個值。這些 SQL 表示式就像公式一樣,它們是用查詢語言編寫的。您還可以使用它們查詢資料庫以獲取特定資料集。

語法

考慮以下 SELECT 語句的基本語法 -

SELECT column1, column2, columnN 
FROM table_name 
WHERE [CONDITION|EXPRESSION];

有不同型別的 SQL 表示式,如下所述 -

  • 布林型
  • 數值型
  • 日期型

現在讓我們詳細討論一下這些內容。

布林表示式

SQL 布林表示式根據匹配單個值來獲取資料。以下是語法 -

SELECT column1, column2, columnN 
FROM table_name 
WHERE SINGLE VALUE MATCHING EXPRESSION;

考慮 CUSTOMERS 表具有以下記錄 -

SQL> SELECT * FROM CUSTOMERS;
+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+
7 rows in set (0.00 sec)

下表是一個簡單的示例,顯示了各種 SQL 布林表示式的用法 -

SQL> SELECT * FROM CUSTOMERS WHERE SALARY = 10000;
+----+-------+-----+---------+----------+
| ID | NAME  | AGE | ADDRESS | SALARY   |
+----+-------+-----+---------+----------+
|  7 | Muffy |  24 | Indore  | 10000.00 |
+----+-------+-----+---------+----------+
1 row in set (0.00 sec)

數值表示式

這些表示式用於在任何查詢中執行任何數學運算。以下是語法 -

SELECT numerical_expression as  OPERATION_NAME
[FROM table_name
WHERE CONDITION] ;

這裡,numerical_expression 用於數學表示式或任何公式。以下是一個簡單的示例,顯示了 SQL 數值表示式的用法 -

SQL> SELECT (15 + 6) AS ADDITION
+----------+
| ADDITION |
+----------+
|       21 |
+----------+
1 row in set (0.00 sec)

有幾個內建函式,如 avg()、sum()、count() 等,用於執行針對錶或特定表列的聚合資料計算。

SQL> SELECT COUNT(*) AS "RECORDS" FROM CUSTOMERS; 
+---------+
| RECORDS |
+---------+
|       7 |
+---------+
1 row in set (0.00 sec)

日期表示式

日期表示式返回當前系統日期和時間值 -

SQL>  SELECT CURRENT_TIMESTAMP;
+---------------------+
| Current_Timestamp   |
+---------------------+
| 2009-11-12 06:40:23 |
+---------------------+
1 row in set (0.00 sec)

另一個日期表示式如下所示 -

SQL>  SELECT  GETDATE();;
+-------------------------+
| GETDATE                 |
+-------------------------+
| 2009-10-22 12:07:18.140 |
+-------------------------+
1 row in set (0.00 sec)

SQL - 建立資料庫

SQL 的CREATE DATABASE語句用於建立新的 SQL 資料庫。

語法

此 CREATE DATABASE 語句的基本語法如下 -

CREATE DATABASE DatabaseName;

資料庫名稱始終應該在 RDBMS 中唯一。

示例

如果要建立新的資料庫<testDB>,則 CREATE DATABASE 語句將如下所示 -

SQL> CREATE DATABASE testDB;

在建立任何資料庫之前,請確保您具有管理員許可權。建立資料庫後,您可以按照以下步驟在資料庫列表中檢查它 -

SQL> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| AMROOD             |
| TUTORIALSPOINT     |
| mysql              |
| orig               |
| test               |
| testDB             |
+--------------------+
7 rows in set (0.00 sec)

SQL - 刪除或刪除資料庫

SQL 的DROP DATABASE語句用於刪除 SQL 模式中現有的資料庫。

語法

DROP DATABASE 語句的基本語法如下 -

DROP DATABASE DatabaseName;

資料庫名稱始終應該在 RDBMS 中唯一。

示例

如果要刪除現有資料庫<testDB>,則 DROP DATABASE 語句將如下所示 -

SQL> DROP DATABASE testDB;

注意 - 在使用此操作之前請小心,因為刪除現有資料庫會導致資料庫中儲存的完整資訊丟失。

在刪除任何資料庫之前,請確保您具有管理員許可權。刪除資料庫後,您可以按照以下步驟在資料庫列表中檢查它 -

SQL> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| AMROOD             |
| TUTORIALSPOINT     |
| mysql              |
| orig               |
| test               |
+--------------------+
6 rows in set (0.00 sec)

SQL - 選擇資料庫,USE 語句

當 SQL 模式中有多個數據庫時,在開始操作之前,您需要選擇一個數據庫來執行所有操作。

SQL 的USE語句用於在 SQL 模式中選擇任何現有資料庫。

語法

USE 語句的基本語法如下所示 -

USE DatabaseName;

資料庫名稱始終應該在 RDBMS 中唯一。

示例

您可以檢查可用的資料庫,如下所示 -

SQL> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| AMROOD             |
| TUTORIALSPOINT     |
| mysql              |
| orig               |
| test               |
+--------------------+
6 rows in set (0.00 sec)

現在,如果要使用 AMROOD 資料庫,則可以執行以下 SQL 命令並開始使用 AMROOD 資料庫。

SQL> USE AMROOD;

SQL - 建立表

建立基本表涉及命名錶並定義其列以及每列的資料型別。

SQL 的CREATE TABLE語句用於建立新表。

語法

CREATE TABLE 語句的基本語法如下 -

CREATE TABLE table_name(
   column1 datatype,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
   PRIMARY KEY( one or more columns )
);

CREATE TABLE 是告訴資料庫系統您想要做什麼的關鍵字。在這種情況下,您想要建立一個新表。表的唯一名稱或識別符號位於 CREATE TABLE 語句之後。

然後在括號中是定義表中每一列以及它是什麼型別資料的列表。透過以下示例,語法變得更加清晰。

可以使用 CREATE TABLE 語句和 SELECT 語句的組合來建立現有表的副本。您可以在使用另一個表建立表中檢視完整詳細資訊。

示例

以下程式碼塊是一個示例,它建立了一個 CUSTOMERS 表,其中 ID 作為主鍵,NOT NULL 是約束條件,表示在建立此表中的記錄時,這些欄位不能為 NULL -

SQL> CREATE TABLE CUSTOMERS(
   ID   INT              NOT NULL,
   NAME VARCHAR (20)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  CHAR (25) ,
   SALARY   DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);

您可以透過檢視 SQL 伺服器顯示的訊息來驗證您的表是否已成功建立,否則您可以使用以下 DESC 命令 -

SQL> DESC CUSTOMERS;
+---------+---------------+------+-----+---------+-------+
| Field   | Type          | Null | Key | Default | Extra |
+---------+---------------+------+-----+---------+-------+
| ID      | int(11)       | NO   | PRI |         |       |
| NAME    | varchar(20)   | NO   |     |         |       |
| AGE     | int(11)       | NO   |     |         |       |
| ADDRESS | char(25)      | YES  |     | NULL    |       |
| SALARY  | decimal(18,2) | YES  |     | NULL    |       |
+---------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

現在,您在資料庫中可以使用 CUSTOMERS 表來儲存與客戶相關的必要資訊。

SQL - 刪除或刪除表

SQL DROP TABLE 語句用於刪除表定義以及該表的所有資料、索引、觸發器、約束和許可權規範。

注意 - 使用此命令時應非常小心,因為一旦刪除表,則該表中所有可用資訊也將永遠丟失。

語法

此 DROP TABLE 語句的基本語法如下 -

DROP TABLE table_name;

示例

讓我們首先驗證 CUSTOMERS 表,然後將其從資料庫中刪除,如下所示 -

SQL> DESC CUSTOMERS;
+---------+---------------+------+-----+---------+-------+
| Field   | Type          | Null | Key | Default | Extra |
+---------+---------------+------+-----+---------+-------+
| ID      | int(11)       | NO   | PRI |         |       |
| NAME    | varchar(20)   | NO   |     |         |       |
| AGE     | int(11)       | NO   |     |         |       |
| ADDRESS | char(25)      | YES  |     | NULL    |       |
| SALARY  | decimal(18,2) | YES  |     | NULL    |       |
+---------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

這意味著 CUSTOMERS 表在資料庫中可用,因此讓我們現在將其刪除,如下所示。

SQL> DROP TABLE CUSTOMERS;
Query OK, 0 rows affected (0.01 sec)

現在,如果您嘗試使用 DESC 命令,則會收到以下錯誤 -

SQL> DESC CUSTOMERS;
ERROR 1146 (42S02): Table 'TEST.CUSTOMERS' doesn't exist

這裡,TEST 是我們用於示例的資料庫名稱。

SQL - INSERT 查詢

SQL INSERT INTO 語句用於向資料庫中的表新增新的資料行。

語法

INSERT INTO 語句有兩個基本語法,如下所示。

INSERT INTO TABLE_NAME (column1, column2, column3,...columnN)  
VALUES (value1, value2, value3,...valueN);

這裡,column1、column2、column3...columnN 是您要向其中插入資料的表的列名。

如果您要為表的所有列新增值,則可能不需要在 SQL 查詢中指定列名。但請確保值的順序與表中列的順序相同。

SQL INSERT INTO 語法如下 -

INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);

示例

以下語句將在 CUSTOMERS 表中建立六條記錄。

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (3, 'kaushik', 23, 'Kota', 2000.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Chaitali', 25, 'Mumbai', 6500.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (5, 'Hardik', 27, 'Bhopal', 8500.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (6, 'Komal', 22, 'MP', 4500.00 );

您可以使用第二個語法在 CUSTOMERS 表中建立記錄,如下所示。

INSERT INTO CUSTOMERS 
VALUES (7, 'Muffy', 24, 'Indore', 10000.00 );

所有上述語句將在 CUSTOMERS 表中生成以下記錄,如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

使用另一個表填充一個表

您可以透過對另一個表執行 select 語句將資料填充到表中;前提是另一個表具有一組欄位,這些欄位是填充第一個表所需的。

語法如下 -

INSERT INTO first_table_name [(column1, column2, ... columnN)] 
   SELECT column1, column2, ...columnN 
   FROM second_table_name
   [WHERE condition];

SQL - SELECT 查詢

SQL SELECT 語句用於從資料庫表中提取資料,該資料以結果表的格式返回這些資料。這些結果表稱為結果集。

語法

SELECT 語句的基本語法如下 -

SELECT column1, column2, columnN FROM table_name;

這裡,column1、column2... 是您想要提取其值的表的欄位。如果要提取欄位中所有可用的欄位,則可以使用以下語法。

SELECT * FROM table_name;

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下程式碼是一個示例,它將提取 CUSTOMERS 表中可用的客戶的 ID、Name 和 Salary 欄位。

SQL> SELECT ID, NAME, SALARY FROM CUSTOMERS;

這將產生以下結果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  1 | Ramesh   |  2000.00 |
|  2 | Khilan   |  1500.00 |
|  3 | kaushik  |  2000.00 |
|  4 | Chaitali |  6500.00 |
|  5 | Hardik   |  8500.00 |
|  6 | Komal    |  4500.00 |
|  7 | Muffy    | 10000.00 |
+----+----------+----------+

如果要提取 CUSTOMERS 表的所有欄位,則應使用以下查詢。

SQL> SELECT * FROM CUSTOMERS;

這將產生如下所示的結果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

SQL - WHERE 子句

SQL WHERE 子句用於在從單個表或透過連線多個表提取資料時指定條件。如果滿足給定條件,則僅返回表中的特定值。您應該使用 WHERE 子句過濾記錄並僅提取必要的記錄。

WHERE 子句不僅用於 SELECT 語句,還用於 UPDATE、DELETE 語句等,我們將在後續章節中對其進行檢查。

語法

帶有 WHERE 子句的 SELECT 語句的基本語法如下所示。

SELECT column1, column2, columnN 
FROM table_name
WHERE [condition]

您可以使用比較或邏輯運算子(如 >、<、=、LIKE、NOT 等)指定條件。以下示例將使此概念更加清晰。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下程式碼是一個示例,它將從 CUSTOMERS 表中提取 ID、Name 和 Salary 欄位,其中 Salary 大於 2000 -

SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE SALARY > 2000;

這將產生以下結果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  4 | Chaitali |  6500.00 |
|  5 | Hardik   |  8500.00 |
|  6 | Komal    |  4500.00 |
|  7 | Muffy    | 10000.00 |
+----+----------+----------+

以下查詢是一個示例,它將從 CUSTOMERS 表中提取 ID、Name 和 Salary 欄位,用於名稱為 Hardik 的客戶。

這裡,需要注意的是,所有字串都應放在單引號('')內。而數值應在沒有任何引號的情況下給出,如上述示例所示。
SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE NAME = 'Hardik';

這將產生以下結果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  5 | Hardik   |  8500.00 |
+----+----------+----------+

SQL - AND 和 OR 連線運算子

SQL AND & OR 運算子用於組合多個條件以縮小 SQL 語句中的資料範圍。這兩個運算子稱為連線運算子。

這些運算子提供了一種方法,可以在同一個 SQL 語句中使用不同的運算子進行多次比較。

AND 運算子

AND 運算子允許 SQL 語句的 WHERE 子句中存在多個條件。

語法

帶有 WHERE 子句的 AND 運算子的基本語法如下 -

SELECT column1, column2, columnN 
FROM table_name
WHERE [condition1] AND [condition2]...AND [conditionN];

您可以使用 AND 運算子組合 N 個條件。對於 SQL 語句要執行的操作,無論是事務還是查詢,由 AND 分隔的所有條件都必須為 TRUE。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一個示例,它將從 CUSTOMERS 表中提取 ID、Name 和 Salary 欄位,其中 Salary 大於 2000 且年齡小於 25 歲 -

SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE SALARY > 2000 AND age < 25;

這將產生以下結果 -

+----+-------+----------+
| ID | NAME  | SALARY   |
+----+-------+----------+
|  6 | Komal |  4500.00 |
|  7 | Muffy | 10000.00 |
+----+-------+----------+

OR 運算子

OR 運算子用於組合 SQL 語句的 WHERE 子句中的多個條件。

語法

帶有 WHERE 子句的 OR 運算子的基本語法如下 -

SELECT column1, column2, columnN 
FROM table_name
WHERE [condition1] OR [condition2]...OR [conditionN]

您可以使用 OR 運算子組合 N 個條件。對於 SQL 語句要執行的操作,無論是事務還是查詢,由 OR 分隔的條件中只有一個必須為 TRUE。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下程式碼塊包含一個查詢,該查詢將從 CUSTOMERS 表中提取 ID、Name 和 Salary 欄位,其中 Salary 大於 2000 或年齡小於 25 歲。

SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE SALARY > 2000 OR age < 25;

這將產生以下結果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  3 | kaushik  |  2000.00 |
|  4 | Chaitali |  6500.00 |
|  5 | Hardik   |  8500.00 |
|  6 | Komal    |  4500.00 |
|  7 | Muffy    | 10000.00 |
+----+----------+----------+

SQL - UPDATE 查詢

SQL UPDATE 查詢用於修改表中現有的記錄。您可以將 WHERE 子句與 UPDATE 查詢一起使用來更新選定的行,否則所有行都將受到影響。

語法

帶有 WHERE 子句的 UPDATE 查詢的基本語法如下 -

UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];

您可以使用 AND 或 OR 運算子組合 N 個條件。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下查詢將更新表中 ID 號為 6 的客戶的 ADDRESS。

SQL> UPDATE CUSTOMERS
SET ADDRESS = 'Pune'
WHERE ID = 6;

現在,CUSTOMERS 表將具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | Pune      |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

如果要修改 CUSTOMERS 表中的所有 ADDRESS 和 SALARY 列值,則不需要使用 WHERE 子句,因為 UPDATE 查詢就足夠了,如下面的程式碼塊所示。

SQL> UPDATE CUSTOMERS
SET ADDRESS = 'Pune', SALARY = 1000.00;

現在,CUSTOMERS 表將具有以下記錄 -

+----+----------+-----+---------+---------+
| ID | NAME     | AGE | ADDRESS | SALARY  |
+----+----------+-----+---------+---------+
|  1 | Ramesh   |  32 | Pune    | 1000.00 |
|  2 | Khilan   |  25 | Pune    | 1000.00 |
|  3 | kaushik  |  23 | Pune    | 1000.00 |
|  4 | Chaitali |  25 | Pune    | 1000.00 |
|  5 | Hardik   |  27 | Pune    | 1000.00 |
|  6 | Komal    |  22 | Pune    | 1000.00 |
|  7 | Muffy    |  24 | Pune    | 1000.00 |
+----+----------+-----+---------+---------+

SQL - DELETE 查詢

SQL DELETE 查詢用於從表中刪除現有記錄。

您可以將 WHERE 子句與 DELETE 查詢一起使用來刪除選定的行,否則所有記錄都將被刪除。

語法

帶有 WHERE 子句的 DELETE 查詢的基本語法如下 -

DELETE FROM table_name
WHERE [condition];

您可以使用 AND 或 OR 運算子組合 N 個條件。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下程式碼包含一個查詢,該查詢將刪除 ID 為 6 的客戶。

SQL> DELETE FROM CUSTOMERS
WHERE ID = 6;

現在,CUSTOMERS 表將具有以下記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

如果要從 CUSTOMERS 表中刪除所有記錄,則不需要使用 WHERE 子句,DELETE 查詢如下 -

SQL> DELETE FROM CUSTOMERS;

現在,CUSTOMERS 表將沒有任何記錄。

SQL - LIKE 子句

SQL LIKE 子句用於使用萬用字元運算子將值與類似值進行比較。有兩種萬用字元與 LIKE 運算子一起使用。

  • 百分號 (%)
  • 下劃線 (_)

百分號表示零個、一個或多個字元。下劃線表示單個數字或字元。這些符號可以組合使用。

語法

% 和 _ 的基本語法如下 -

SELECT FROM table_name
WHERE column LIKE 'XXXX%'

or 

SELECT FROM table_name
WHERE column LIKE '%XXXX%'

or

SELECT FROM table_name
WHERE column LIKE 'XXXX_'

or

SELECT FROM table_name
WHERE column LIKE '_XXXX'

or

SELECT FROM table_name
WHERE column LIKE '_XXXX_'

您可以使用 AND 或 OR 運算子組合 N 個條件。這裡,XXXX 可以是任何數值或字串值。

示例

下表顯示了一些示例,其中 WHERE 部分具有不同的 LIKE 子句以及 '%' 和 '_' 運算子 -

序號 語句 & 描述
1

WHERE SALARY LIKE '200%'

查詢以 200 開頭的任何值。

2

WHERE SALARY LIKE '%200%'

查詢在任何位置包含 200 的任何值。

3

WHERE SALARY LIKE '_00%'

查詢在第二個和第三個位置包含 00 的任何值。

4

WHERE SALARY LIKE '2_%_%'

查詢以 2 開頭且至少包含 3 個字元的任何值。

5

WHERE SALARY LIKE '%2'

查詢以 2 結尾的任何值。

6

WHERE SALARY LIKE '_2%3'

查詢在第二個位置包含 2 且以 3 結尾的任何值。

7

WHERE SALARY LIKE '2___3'

查詢五位數中以 2 開頭並以 3 結尾的任何值。

讓我們舉一個真實的例子,考慮 CUSTOMERS 表具有如下所示的記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一個示例,它將顯示 CUSTOMERS 表中的所有記錄,其中 SALARY 以 200 開頭。

SQL> SELECT * FROM CUSTOMERS
WHERE SALARY LIKE '200%';

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
+----+----------+-----+-----------+----------+

SQL - TOP、LIMIT 或 ROWNUM 子句

SQL TOP 子句用於從表中提取前 N 個或 X% 的記錄。

注意 - 所有資料庫都不支援 TOP 子句。例如,MySQL 使用 LIMIT 子句來提取有限數量的記錄,而 Oracle 使用 ROWNUM 命令來提取有限數量的記錄。

語法

帶有 SELECT 語句的 TOP 子句的基本語法如下。

SELECT TOP number|percent column_name(s)
FROM table_name
WHERE [condition]

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下查詢是 SQL 伺服器上的一個示例,它將從 CUSTOMERS 表中提取前 3 條記錄。

SQL> SELECT TOP 3 * FROM CUSTOMERS;

這將產生以下結果 -

+----+---------+-----+-----------+---------+
| ID | NAME    | AGE | ADDRESS   | SALARY  |
+----+---------+-----+-----------+---------+
|  1 | Ramesh  |  32 | Ahmedabad | 2000.00 |
|  2 | Khilan  |  25 | Delhi     | 1500.00 |
|  3 | kaushik |  23 | Kota      | 2000.00 |
+----+---------+-----+-----------+---------+

如果您使用的是 MySQL 伺服器,則以下是一個等效的示例 -

SQL> SELECT * FROM CUSTOMERS
LIMIT 3;

這將產生以下結果 -

+----+---------+-----+-----------+---------+
| ID | NAME    | AGE | ADDRESS   | SALARY  |
+----+---------+-----+-----------+---------+
|  1 | Ramesh  |  32 | Ahmedabad | 2000.00 |
|  2 | Khilan  |  25 | Delhi     | 1500.00 |
|  3 | kaushik |  23 | Kota      | 2000.00 |
+----+---------+-----+-----------+---------+

如果您使用的是 Oracle 伺服器,則以下程式碼塊包含一個等效的示例。

SQL> SELECT * FROM CUSTOMERS
WHERE ROWNUM <= 3;

這將產生以下結果 -

+----+---------+-----+-----------+---------+
| ID | NAME    | AGE | ADDRESS   | SALARY  |
+----+---------+-----+-----------+---------+
|  1 | Ramesh  |  32 | Ahmedabad | 2000.00 |
|  2 | Khilan  |  25 | Delhi     | 1500.00 |
|  3 | kaushik |  23 | Kota      | 2000.00 |
+----+---------+-----+-----------+---------+

SQL - ORDER BY 子句

SQL ORDER BY 子句用於根據一個或多個列對資料進行升序或降序排序。某些資料庫預設按升序對查詢結果進行排序。

語法

ORDER BY 子句的基本語法如下 -

SELECT column-list 
FROM table_name 
[WHERE condition] 
[ORDER BY column1, column2, .. columnN] [ASC | DESC];

您可以在 ORDER BY 子句中使用多個列。請確保您用於排序的任何列都在列列表中。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下程式碼塊包含一個示例,它將按 NAME 和 SALARY 的升序對結果進行排序 -

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME, SALARY;

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

以下程式碼塊包含一個示例,它將按 NAME 的降序對結果進行排序。

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME DESC;

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
+----+----------+-----+-----------+----------+

SQL - Group By

SQL GROUP BY 子句與 SELECT 語句一起使用,將相同的資料排列成組。此 GROUP BY 子句位於 SELECT 語句中的 WHERE 子句之後,並且位於 ORDER BY 子句之前。

語法

以下程式碼塊顯示了 GROUP BY 子句的基本語法。GROUP BY 子句必須位於 WHERE 子句中的條件之後,並且如果使用 ORDER BY 子句,則必須位於 ORDER BY 子句之前。

SELECT column1, column2
FROM table_name
WHERE [ conditions ]
GROUP BY column1, column2
ORDER BY column1, column2

示例

假設 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

如果要了解每個客戶的工資總額,則 GROUP BY 查詢如下所示。

SQL> SELECT NAME, SUM(SALARY) FROM CUSTOMERS
   GROUP BY NAME;

這將產生以下結果 -

+----------+-------------+
| NAME     | SUM(SALARY) |
+----------+-------------+
| Chaitali |     6500.00 |
| Hardik   |     8500.00 |
| kaushik  |     2000.00 |
| Khilan   |     1500.00 |
| Komal    |     4500.00 |
| Muffy    |    10000.00 |
| Ramesh   |     2000.00 |
+----------+-------------+

現在,讓我們看一個 CUSTOMERS 表具有以下包含重複名稱的記錄的表 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Ramesh   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | kaushik  |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

現在,如果要再次瞭解每個客戶的工資總額,則 GROUP BY 查詢如下所示 -

SQL> SELECT NAME, SUM(SALARY) FROM CUSTOMERS
   GROUP BY NAME;

這將產生以下結果 -

+---------+-------------+
| NAME    | SUM(SALARY) |
+---------+-------------+
| Hardik  |     8500.00 |
| kaushik |     8500.00 |
| Komal   |     4500.00 |
| Muffy   |    10000.00 |
| Ramesh  |     3500.00 |
+---------+-------------+

SQL - Distinct 關鍵字

SQL 的DISTINCT關鍵字與SELECT語句一起使用,用於消除所有重複記錄並僅獲取唯一記錄。

在表中可能存在多個重複記錄的情況。在獲取此類記錄時,獲取唯一記錄而不是獲取重複記錄更有意義。

語法

用於消除重複記錄的DISTINCT關鍵字的基本語法如下所示:

SELECT DISTINCT column1, column2,.....columnN 
FROM table_name
WHERE [condition]

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

首先,讓我們看看以下SELECT查詢如何返回重複的工資記錄。

SQL> SELECT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

這將產生以下結果,其中工資(2000)出現了兩次,這是原始表中的重複記錄。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

現在,讓我們在上面的SELECT查詢中使用DISTINCT關鍵字,然後檢視結果。

SQL> SELECT DISTINCT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

這將產生以下結果,其中我們沒有任何重複條目。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

SQL - 排序結果

SQL ORDER BY 子句用於根據一個或多個列對資料進行升序或降序排序。某些資料庫預設按升序對查詢結果進行排序。

語法

用於按升序或降序排序結果的ORDER BY子句的基本語法如下所示:

SELECT column-list 
FROM table_name 
[WHERE condition] 
[ORDER BY column1, column2, .. columnN] [ASC | DESC];

您可以在ORDER BY子句中使用多個列。請確保您用於排序的任何列都必須在列列表中。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一個示例,它將按NAME和SALARY升序排序結果。

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME, SALARY;

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

以下程式碼塊包含一個示例,它將按NAME降序排序結果。

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME DESC;

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
+----+----------+-----+-----------+----------+

要按自己的首選順序獲取行,將使用以下SELECT查詢:

SQL> SELECT * FROM CUSTOMERS
   ORDER BY (CASE ADDRESS
   WHEN 'DELHI' 	 THEN 1
   WHEN 'BHOPAL' 	 THEN 2
   WHEN 'KOTA' 	 THEN 3
   WHEN 'AHMEDABAD' THEN 4
   WHEN 'MP' 	THEN 5
   ELSE 100 END) ASC, ADDRESS DESC;

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

這將根據您ownoOrder的首選項按ADDRESS對客戶進行排序,並對其餘地址按自然順序排序。此外,其餘地址將按反字母順序排序。

SQL - 約束

約束是對錶的資料列強制執行的規則。它們用於限制可以輸入表的的資料型別。這確保了資料庫中資料的準確性和可靠性。

約束可以是列級約束或表級約束。列級約束僅應用於一列,而表級約束應用於整個表。

以下是SQL中一些最常用的約束。這些約束已在SQL - RDBMS 概念章節中討論過,但在這一點上值得複習。

  • NOT NULL 約束 - 確保列不能具有NULL值。

  • UNIQUE 約束 - 確保列中的所有值都不同。

  • 主鍵 - 唯一標識資料庫表中的每一行/記錄。

  • FOREIGN KEY - 唯一標識任何給定資料庫表中的一行/記錄。

  • 索引 - 用於非常快速地建立和檢索資料庫中的資料。

可以在建立表時使用CREATE TABLE語句指定約束,或者您也可以在建立表後使用ALTER TABLE語句建立約束。

刪除約束

您可以使用ALTER TABLE命令和DROP CONSTRAINT選項刪除已定義的任何約束。

例如,要刪除EMPLOYEES表中的主鍵約束,可以使用以下命令。

ALTER TABLE EMPLOYEES DROP CONSTRAINT EMPLOYEES_PK;

某些實現可能提供刪除某些約束的快捷方式。例如,要在Oracle中刪除表的PrimaryKey約束,可以使用以下命令。

ALTER TABLE EMPLOYEES DROP PRIMARY KEY;

某些實現允許您停用約束。與其永久地從資料庫中刪除約束,不如暫時停用約束,然後稍後啟用它。

完整性約束

完整性約束用於確保關係資料庫中資料的準確性和一致性。關係資料庫透過參照完整性的概念來處理資料完整性。

有許多型別的完整性約束在參照完整性 (RI)中發揮作用。這些約束包括主鍵、外部索引鍵、唯一約束和其他上面提到的約束。

SQL - 使用連線

SQL 的Joins子句用於組合資料庫中兩個或多個表中的記錄。JOIN 是一種透過使用每個表共有的值來組合兩個表中的欄位的方法。

考慮以下兩個表:

表 1 - CUSTOMERS 表

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

現在,讓我們在SELECT語句中連線這兩個表,如下所示。

SQL> SELECT ID, NAME, AGE, AMOUNT
   FROM CUSTOMERS, ORDERS
   WHERE  CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

這將產生以下結果。

+----+----------+-----+--------+
| ID | NAME     | AGE | AMOUNT |
+----+----------+-----+--------+
|  3 | kaushik  |  23 |   3000 |
|  3 | kaushik  |  23 |   1500 |
|  2 | Khilan   |  25 |   1560 |
|  4 | Chaitali |  25 |   2060 |
+----+----------+-----+--------+

這裡,可以注意到連線是在WHERE子句中執行的。可以使用多個運算子來連線表,例如=、<、>、<>、<=、>=、!=、BETWEEN、LIKE和NOT;它們都可以用於連線表。但是,最常見的運算子是等於符號。

SQL中有多種型別的連線:

  • INNER JOIN - 當兩個表中都存在匹配項時返回行。

  • LEFT JOIN - 返回左側表中的所有行,即使右側表中沒有匹配項。

  • RIGHT JOIN - 返回右側表中的所有行,即使左側表中沒有匹配項。

  • FULL JOIN - 當其中一個表中存在匹配項時返回行。

  • SELF JOIN - 用於將表本身連線起來,就好像該表是兩個表一樣,在SQL語句中臨時重新命名至少一個表。

現在讓我們詳細討論每個連線。

SQL - UNION 子句

SQL UNION 子句/運算子用於組合兩個或多個SELECT語句的結果,而不返回任何重複行。

要使用此UNION子句,每個SELECT語句必須具有

  • 相同數量的選定列
  • 相同數量的列表達式
  • 相同的資料型別,並且
  • 按相同的順序排列

但它們不必具有相同的長度。

語法

UNION子句的基本語法如下所示:

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

這裡,給定的條件可以是基於您的需求的任何給定表示式。

示例

考慮以下兩個表。

表 1 - CUSTOMERS 表如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表如下所示。

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

現在,讓我們在SELECT語句中連線這兩個表,如下所示:

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

這將產生以下結果 -

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    1 | Ramesh   |   NULL | NULL                |
|    2 | Khilan   |   1560 | 2009-11-20 00:00:00 |
|    3 | kaushik  |   3000 | 2009-10-08 00:00:00 |
|    3 | kaushik  |   1500 | 2009-10-08 00:00:00 |
|    4 | Chaitali |   2060 | 2008-05-20 00:00:00 |
|    5 | Hardik   |   NULL | NULL                |
|    6 | Komal    |   NULL | NULL                |
|    7 | Muffy    |   NULL | NULL                |
+------+----------+--------+---------------------+

UNION ALL 子句

UNION ALL運算子用於組合兩個SELECT語句的結果,包括重複行。

應用於UNION子句的相同規則將應用於UNION ALL運算子。

語法

UNION ALL的基本語法如下所示。

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION ALL

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

這裡,給定的條件可以是基於您的需求的任何給定表示式。

示例

考慮以下兩個表,

表 1 - CUSTOMERS 表如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表如下所示。

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

現在,讓我們在SELECT語句中連線這兩個表,如下所示:

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION ALL
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

這將產生以下結果 -

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    1 | Ramesh   |   NULL | NULL                |
|    2 | Khilan   |   1560 | 2009-11-20 00:00:00 |
|    3 | kaushik  |   3000 | 2009-10-08 00:00:00 |
|    3 | kaushik  |   1500 | 2009-10-08 00:00:00 |
|    4 | Chaitali |   2060 | 2008-05-20 00:00:00 |
|    5 | Hardik   |   NULL | NULL                |
|    6 | Komal    |   NULL | NULL                |
|    7 | Muffy    |   NULL | NULL                |
|    3 | kaushik  |   3000 | 2009-10-08 00:00:00 |
|    3 | kaushik  |   1500 | 2009-10-08 00:00:00 |
|    2 | Khilan   |   1560 | 2009-11-20 00:00:00 |
|    4 | Chaitali |   2060 | 2008-05-20 00:00:00 |
+------+----------+--------+---------------------+

還有另外兩個子句(即運算子),它們類似於UNION子句。

  • SQL INTERSECT 子句 - 用於組合兩個SELECT語句,但僅返回第一個SELECT語句中與第二個SELECT語句中的一行相同的行。

  • SQL EXCEPT 子句 - 組合兩個SELECT語句並返回第一個SELECT語句中未由第二個SELECT語句返回的行。

SQL - NULL 值

SQL 的NULL是用於表示缺失值的術語。表中的NULL值是指欄位中看起來為空白的值。

具有NULL值的欄位是沒有值的欄位。務必瞭解,NULL值不同於零值或包含空格的欄位。

語法

建立表時NULL的基本語法。

SQL> CREATE TABLE CUSTOMERS(
   ID   INT              NOT NULL,
   NAME VARCHAR (20)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  CHAR (25) ,
   SALARY   DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);

這裡,NOT NULL表示列應始終接受給定資料型別的顯式值。在兩列中我們沒有使用NOT NULL,這意味著這些列可以為NULL。

具有NULL值的欄位是在記錄建立期間留空的部分。

示例

NULL值在選擇資料時可能會導致問題。但是,因為當將未知值與任何其他值進行比較時,結果始終是未知的並且不包含在結果中。您必須使用IS NULLIS NOT NULL運算子來檢查NULL值。

考慮以下CUSTOMERS表,其中包含如下所示的記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |          |
|  7 | Muffy    |  24 | Indore    |          |
+----+----------+-----+-----------+----------+

現在,以下是IS NOT NULL運算子的用法。

SQL> SELECT  ID, NAME, AGE, ADDRESS, SALARY
   FROM CUSTOMERS
   WHERE SALARY IS NOT NULL;

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
+----+----------+-----+-----------+----------+

現在,以下是IS NULL運算子的用法。

SQL> SELECT  ID, NAME, AGE, ADDRESS, SALARY
   FROM CUSTOMERS
   WHERE SALARY IS NULL;

這將產生以下結果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  6 | Komal    |  22 | MP        |          |
|  7 | Muffy    |  24 | Indore    |          |
+----+----------+-----+-----------+----------+

SQL - 別名語法

您可以透過賦予另一個稱為別名的名稱來臨時重命名錶或列。使用表別名的目的是在特定的SQL語句中重命名錶。重新命名是臨時更改,實際的表名不會在資料庫中更改。列別名用於重命名錶的列,以便於特定的SQL查詢。

語法

別名的基本語法如下所示。

SELECT column1, column2....
FROM table_name AS alias_name
WHERE [condition];

別名的基本語法如下所示。

SELECT column_name AS alias_name
FROM table_name
WHERE [condition];

示例

考慮以下兩個表。

表 1 - CUSTOMERS 表如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表如下所示。

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

現在,以下程式碼塊顯示了表別名的用法。

SQL> SELECT C.ID, C.NAME, C.AGE, O.AMOUNT 
   FROM CUSTOMERS AS C, ORDERS AS O
   WHERE  C.ID = O.CUSTOMER_ID;

這將產生以下結果。

+----+----------+-----+--------+
| ID | NAME     | AGE | AMOUNT |
+----+----------+-----+--------+
|  3 | kaushik  |  23 |   3000 |
|  3 | kaushik  |  23 |   1500 |
|  2 | Khilan   |  25 |   1560 |
|  4 | Chaitali |  25 |   2060 |
+----+----------+-----+--------+

以下是列別名的用法。

SQL> SELECT  ID AS CUSTOMER_ID, NAME AS CUSTOMER_NAME
   FROM CUSTOMERS
   WHERE SALARY IS NOT NULL;

這將產生以下結果。

+-------------+---------------+
| CUSTOMER_ID | CUSTOMER_NAME |
+-------------+---------------+
|           1 | Ramesh        |
|           2 | Khilan        |
|           3 | kaushik       |
|           4 | Chaitali      |
|           5 | Hardik        |
|           6 | Komal         |
|           7 | Muffy         |
+-------------+---------------+

SQL - 索引

索引是資料庫搜尋引擎可以使用來加快資料檢索速度的特殊查詢表。簡單來說,索引是指向表中資料的指標。資料庫中的索引與書籍後面的索引非常相似。

例如,如果您想引用一本書中討論某個特定主題的所有頁面,您首先參考索引,該索引按字母順序列出所有主題,然後參考一個或多個特定的頁碼。

索引有助於加快SELECT查詢和WHERE子句的速度,但會降低資料輸入速度,包括UPDATEINSERT語句。建立或刪除索引不會影響資料。

建立索引涉及CREATE INDEX語句,該語句允許您命名索引,指定表以及要索引的列或列,並指示索引是按升序還是降序排列。

索引也可以是唯一的,就像UNIQUE約束一樣,因為索引可以防止在存在索引的列或列組合中插入重複項。

CREATE INDEX 命令

CREATE INDEX的基本語法如下所示。

CREATE INDEX index_name ON table_name;

單列索引

單列索引是基於一個表列建立的。基本語法如下所示。

CREATE INDEX index_name
ON table_name (column_name);

唯一索引

唯一索引不僅用於效能,還用於資料完整性。唯一索引不允許將任何重複值插入表中。基本語法如下所示。

CREATE UNIQUE INDEX index_name
on table_name (column_name);

複合索引

複合索引是表中兩列或多列上的索引。其基本語法如下所示。

CREATE INDEX index_name
on table_name (column1, column2);

無論建立單列索引還是複合索引,都要考慮在查詢的WHERE子句中經常用作篩選條件的列。

如果只有一列使用,則應選擇單列索引。如果在WHERE子句中經常使用兩列或多列作為篩選器,則複合索引將是最佳選擇。

隱式索引

隱式索引是在建立物件時由資料庫伺服器自動建立的索引。主鍵約束和唯一約束會自動建立索引。

DROP INDEX 命令

可以使用 SQL 的 **DROP** 命令刪除索引。刪除索引時應謹慎操作,因為這可能會導致效能下降或提升。

基本語法如下:

DROP INDEX index_name;

您可以檢視 索引約束 章節以檢視有關索引的一些實際示例。

何時應避免使用索引?

儘管索引旨在提高資料庫的效能,但在某些情況下應避免使用它們。

以下指南說明了何時應重新考慮使用索引。

  • 不應在小型表上使用索引。

  • 頻繁進行大量批次更新或插入操作的表。

  • 不應在包含大量 NULL 值的列上使用索引。

  • 不應為經常被修改的列建立索引。

SQL - ALTER TABLE 命令

SQL 的 **ALTER TABLE** 命令用於在現有表中新增、刪除或修改列。您還應使用 ALTER TABLE 命令在現有表上新增和刪除各種約束。

語法

在現有表中新增 **新列** 的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name ADD column_name datatype;

在現有表中 **刪除列** 的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name DROP COLUMN column_name;

更改表中列的 **資料型別** 的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name MODIFY COLUMN column_name datatype;

在表中列上新增 **NOT NULL** 約束的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name MODIFY column_name datatype NOT NULL;

向表新增 **唯一約束** 的 ALTER TABLE 的基本語法如下。

ALTER TABLE table_name 
ADD CONSTRAINT MyUniqueConstraint UNIQUE(column1, column2...);

向表新增 **CHECK 約束** 的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name 
ADD CONSTRAINT MyUniqueConstraint CHECK (CONDITION);

向表新增 **主鍵** 約束的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name 
ADD CONSTRAINT MyPrimaryKey PRIMARY KEY (column1, column2...);

從表中 **刪除約束** 的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name 
DROP CONSTRAINT MyUniqueConstraint;

如果您使用的是 MySQL,則程式碼如下:

ALTER TABLE table_name 
DROP INDEX MyUniqueConstraint;

從表中 **刪除主鍵** 約束的 ALTER TABLE 命令的基本語法如下。

ALTER TABLE table_name 
DROP CONSTRAINT MyPrimaryKey;

如果您使用的是 MySQL,則程式碼如下:

ALTER TABLE table_name 
DROP PRIMARY KEY;

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是向現有表新增 **新列** 的示例:

ALTER TABLE CUSTOMERS ADD SEX char(1);

現在,CUSTOMERS 表已更改,以下將是 SELECT 語句的輸出。

+----+---------+-----+-----------+----------+------+
| ID | NAME    | AGE | ADDRESS   | SALARY   | SEX  |
+----+---------+-----+-----------+----------+------+
|  1 | Ramesh  |  32 | Ahmedabad |  2000.00 | NULL |
|  2 | Ramesh  |  25 | Delhi     |  1500.00 | NULL |
|  3 | kaushik |  23 | Kota      |  2000.00 | NULL |
|  4 | kaushik |  25 | Mumbai    |  6500.00 | NULL |
|  5 | Hardik  |  27 | Bhopal    |  8500.00 | NULL |
|  6 | Komal   |  22 | MP        |  4500.00 | NULL |
|  7 | Muffy   |  24 | Indore    | 10000.00 | NULL |
+----+---------+-----+-----------+----------+------+

以下是從現有表中刪除 sex 列的示例。

ALTER TABLE CUSTOMERS DROP SEX;

現在,CUSTOMERS 表已更改,以下將是 SELECT 語句的輸出。

+----+---------+-----+-----------+----------+
| ID | NAME    | AGE | ADDRESS   | SALARY   |
+----+---------+-----+-----------+----------+
|  1 | Ramesh  |  32 | Ahmedabad |  2000.00 |
|  2 | Ramesh  |  25 | Delhi     |  1500.00 |
|  3 | kaushik |  23 | Kota      |  2000.00 |
|  4 | kaushik |  25 | Mumbai    |  6500.00 |
|  5 | Hardik  |  27 | Bhopal    |  8500.00 |
|  6 | Komal   |  22 | MP        |  4500.00 |
|  7 | Muffy   |  24 | Indore    | 10000.00 |
+----+---------+-----+-----------+----------+

SQL - TRUNCATE TABLE 命令

SQL 的 **TRUNCATE TABLE** 命令用於刪除現有表中的所有資料。

您還可以使用 DROP TABLE 命令刪除整個表,但這會從資料庫中刪除整個表結構,並且如果您希望儲存一些資料,則需要重新建立此表。

語法

**TRUNCATE TABLE** 命令的基本語法如下。

TRUNCATE TABLE  table_name;

示例

假設 CUSTOMERS 表包含以下記錄:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是 Truncate 命令的示例。

SQL > TRUNCATE TABLE CUSTOMERS;

現在,CUSTOMERS 表已被截斷,SELECT 語句的輸出將如以下程式碼塊所示:

SQL> SELECT * FROM CUSTOMERS;
Empty set (0.00 sec)

SQL - 使用檢視

檢視只不過是儲存在資料庫中並具有關聯名稱的 SQL 語句。檢視實際上是以預定義的 SQL 查詢形式組成的表。

檢視可以包含表的全部行或表的選定行。檢視可以從一個或多個表建立,這取決於用於建立檢視的 SQL 查詢。

檢視是一種虛擬表,允許使用者執行以下操作:

  • 以使用者或使用者類別認為自然或直觀的方式組織資料。

  • 以這樣一種方式限制對資料的訪問:使用者只能檢視(有時)修改他們需要的內容,而不能檢視更多內容。

  • 彙總來自各個表的的資料,這些資料可用於生成報表。

建立檢視

資料庫檢視使用 **CREATE VIEW** 語句建立。檢視可以從單個表、多個表或另一個檢視建立。

要建立檢視,使用者必須根據特定實現擁有相應的系統許可權。

基本的 **CREATE VIEW** 語法如下:

CREATE VIEW view_name AS
SELECT column1, column2.....
FROM table_name
WHERE [condition];

您可以像在普通 SQL SELECT 查詢中使用它們一樣,在 SELECT 語句中包含多個表。

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是如何從 CUSTOMERS 表建立檢視的示例。此檢視將用於獲取 CUSTOMERS 表中的客戶姓名和年齡。

SQL > CREATE VIEW CUSTOMERS_VIEW AS
SELECT name, age
FROM  CUSTOMERS;

現在,您可以像查詢實際表一樣查詢 CUSTOMERS_VIEW。以下是一個示例。

SQL > SELECT * FROM CUSTOMERS_VIEW;

這將產生以下結果。

+----------+-----+
| name     | age |
+----------+-----+
| Ramesh   |  32 |
| Khilan   |  25 |
| kaushik  |  23 |
| Chaitali |  25 |
| Hardik   |  27 |
| Komal    |  22 |
| Muffy    |  24 |
+----------+-----+

WITH CHECK OPTION

WITH CHECK OPTION 是 CREATE VIEW 語句的一個選項。WITH CHECK OPTION 的目的是確保所有 UPDATE 和 INSERT 都滿足檢視定義中的條件。

如果它們不滿足條件,則 UPDATE 或 INSERT 將返回錯誤。

以下程式碼塊包含使用 WITH CHECK OPTION 建立相同檢視 CUSTOMERS_VIEW 的示例。

CREATE VIEW CUSTOMERS_VIEW AS
SELECT name, age
FROM  CUSTOMERS
WHERE age IS NOT NULL
WITH CHECK OPTION;

在這種情況下,WITH CHECK OPTION 應該拒絕在檢視的 AGE 列中輸入任何 NULL 值,因為檢視由 AGE 列中沒有 NULL 值的資料定義。

更新檢視

在某些條件下可以更新檢視,這些條件如下:

  • SELECT 子句可能不包含 DISTINCT 關鍵字。

  • SELECT 子句可能不包含彙總函式。

  • SELECT 子句可能不包含集合函式。

  • SELECT 子句可能不包含集合運算子。

  • SELECT 子句可能不包含 ORDER BY 子句。

  • FROM 子句可能不包含多個表。

  • WHERE 子句可能不包含子查詢。

  • 查詢可能不包含 GROUP BY 或 HAVING。

  • 不能更新計算列。

  • 為了使 INSERT 查詢正常工作,必須在檢視中包含基表中的所有 NOT NULL 列。

因此,如果檢視滿足上述所有規則,則可以更新該檢視。以下程式碼塊包含更新 Ramesh 年齡的示例。

SQL > UPDATE CUSTOMERS_VIEW
   SET AGE = 35
   WHERE name = 'Ramesh';

這最終將更新基表 CUSTOMERS,並且更改將反映在檢視本身中。現在,嘗試查詢基表,SELECT 語句將產生以下結果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

向檢視中插入行

可以向檢視中插入資料行。適用於 UPDATE 命令的相同規則也適用於 INSERT 命令。

在這裡,我們無法在 CUSTOMERS_VIEW 中插入行,因為我們沒有在此檢視中包含所有 NOT NULL 列,否則您可以像在表中插入行一樣在檢視中插入行。

從檢視中刪除行

可以從檢視中刪除資料行。適用於 UPDATE 和 INSERT 命令的相同規則也適用於 DELETE 命令。

以下是如何刪除 AGE = 22 的記錄的示例。

SQL > DELETE FROM CUSTOMERS_VIEW
   WHERE age = 22;

這最終將從基表 CUSTOMERS 中刪除一行,並且更改將反映在檢視本身中。現在,嘗試查詢基表,SELECT 語句將產生以下結果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

刪除檢視

顯然,如果不再需要檢視,則需要一種方法來刪除它。語法非常簡單,如下所示:

DROP VIEW view_name;

以下是如何從 CUSTOMERS 表中刪除 CUSTOMERS_VIEW 的示例。

DROP VIEW CUSTOMERS_VIEW;

SQL - Having 子句

**HAVING 子句** 使您能夠指定過濾結果集中顯示哪些組結果的條件。

WHERE 子句對選定的列設定條件,而 HAVING 子句對 GROUP BY 子句建立的組設定條件。

語法

以下程式碼塊顯示了查詢中 HAVING 子句的位置。

SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY

HAVING 子句必須跟在查詢中的 GROUP BY 子句之後,並且如果使用 ORDER BY 子句,還必須位於其前面。以下程式碼塊包含包含 HAVING 子句的 SELECT 語句的語法:

SELECT column1, column2
FROM table1, table2
WHERE [ conditions ]
GROUP BY column1, column2
HAVING [ conditions ]
ORDER BY column1, column2

示例

假設 CUSTOMERS 表包含以下記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一個示例,它將顯示與年齡計數相似的記錄,該記錄大於或等於 2。

SQL > SELECT ID, NAME, AGE, ADDRESS, SALARY
FROM CUSTOMERS
GROUP BY age
HAVING COUNT(age) >= 2;

這將產生以下結果 -

+----+--------+-----+---------+---------+
| ID | NAME   | AGE | ADDRESS | SALARY  |
+----+--------+-----+---------+---------+
|  2 | Khilan |  25 | Delhi   | 1500.00 |
+----+--------+-----+---------+---------+

SQL - 事務

事務是在資料庫上執行的工作單元。事務是按邏輯順序完成的工作單元或序列,無論是使用者手動執行還是由某種資料庫程式自動執行。

事務是對資料庫進行的一項或多項更改的傳播。例如,如果您正在建立記錄、更新記錄或從表中刪除記錄,那麼您就是在對該表執行事務。控制這些事務對於確保資料完整性和處理資料庫錯誤非常重要。

實際上,您會將許多 SQL 查詢組合成一個組,並將它們作為一個事務的一部分一起執行。

事務的屬性

事務具有以下四個標準屬性,通常用首字母縮寫詞 **ACID** 來表示。

  • **原子性** - 確保工作單元中的所有操作都成功完成。否則,事務將在發生故障時中止,並且所有先前操作都將回滾到其以前的狀態。

  • **一致性** - 確保資料庫在成功提交事務後正確更改狀態。

  • **隔離性** - 使事務能夠獨立於彼此並透明地執行。

  • **永續性** - 確保提交事務的結果或效果在系統故障的情況下仍然存在。

事務控制

以下命令用於控制事務。

  • **COMMIT** - 儲存更改。

  • **ROLLBACK** - 回滾更改。

  • **SAVEPOINT** - 在事務組中建立回滾點。

  • **SET TRANSACTION** - 為事務命名。

事務控制命令

事務控制命令僅與 **DML 命令** 一起使用,例如 - INSERT、UPDATE 和 DELETE。它們不能用於建立或刪除表,因為這些操作會自動提交到資料庫中。

COMMIT 命令

COMMIT 命令是用於將事務呼叫的更改儲存到資料庫的事務命令。

COMMIT 命令是用於將事務呼叫的更改儲存到資料庫的事務命令。COMMIT 命令將自上次 COMMIT 或 ROLLBACK 命令以來所有事務儲存到資料庫。

COMMIT 命令的語法如下。

COMMIT;

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

下面是一個示例,它將刪除表中年齡等於 25 的所有記錄,然後提交資料庫中的更改。

SQL> DELETE FROM CUSTOMERS
   WHERE AGE = 25;
SQL> COMMIT;

因此,表中的兩行將被刪除,並且 SELECT 語句將產生以下結果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

ROLLBACK 命令

ROLLBACK 命令是用於撤消尚未儲存到資料庫的事務的交易命令。此命令只能用於撤消自上次發出 COMMIT 或 ROLLBACK 命令以來的事務。

ROLLBACK 命令的語法如下所示:

ROLLBACK;

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一個示例,它將刪除表中年齡等於 25 的所有記錄,然後回滾資料庫中的更改。

SQL> DELETE FROM CUSTOMERS
   WHERE AGE = 25;
SQL> ROLLBACK;

因此,刪除操作不會影響表,並且 SELECT 語句將產生以下結果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

SAVEPOINT 命令

SAVEPOINT 是事務中的一個點,您可以在該點將事務回滾到某個特定點,而無需回滾整個事務。

SAVEPOINT 命令的語法如下所示。

SAVEPOINT SAVEPOINT_NAME;

此命令僅用於在所有事務語句中建立 SAVEPOINT。ROLLBACK 命令用於撤消一組事務。

回滾到 SAVEPOINT 的語法如下所示。

ROLLBACK TO SAVEPOINT_NAME;

以下是一個示例,您計劃從 CUSTOMERS 表中刪除三個不同的記錄。您希望在每次刪除之前建立一個 SAVEPOINT,以便您可以隨時回滾到任何 SAVEPOINT 以將相應的資料恢復到其原始狀態。

示例

假設 CUSTOMERS 表包含以下記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下程式碼塊包含一系列操作。

SQL> SAVEPOINT SP1;
Savepoint created.
SQL> DELETE FROM CUSTOMERS WHERE ID=1;
1 row deleted.
SQL> SAVEPOINT SP2;
Savepoint created.
SQL> DELETE FROM CUSTOMERS WHERE ID=2;
1 row deleted.
SQL> SAVEPOINT SP3;
Savepoint created.
SQL> DELETE FROM CUSTOMERS WHERE ID=3;
1 row deleted.

現在三個刪除操作已經完成,假設您改變主意並決定回滾到您標識為 SP2 的 SAVEPOINT。由於 SP2 是在第一次刪除後建立的,因此最後兩次刪除被撤消了:

SQL> ROLLBACK TO SP2;
Rollback complete.

請注意,由於您回滾到 SP2,因此只執行了第一次刪除。

SQL> SELECT * FROM CUSTOMERS;
+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+
6 rows selected.

RELEASE SAVEPOINT 命令

RELEASE SAVEPOINT 命令用於刪除您建立的 SAVEPOINT。

RELEASE SAVEPOINT 命令的語法如下。

RELEASE SAVEPOINT SAVEPOINT_NAME;

釋放 SAVEPOINT 後,您將無法再使用 ROLLBACK 命令撤消自上次 SAVEPOINT 以來執行的事務。

SET TRANSACTION 命令

SET TRANSACTION 命令可用於啟動資料庫事務。此命令用於為後續的事務指定特性。例如,您可以將事務指定為只讀或讀寫。

SET TRANSACTION 命令的語法如下所示。

SET TRANSACTION [ READ WRITE | READ ONLY ];

SQL - 萬用字元運算子

我們已經討論過 SQL LIKE 運算子,它用於使用萬用字元運算子將值與類似值進行比較。

SQL 支援與 LIKE 運算子結合使用的兩個萬用字元運算子,在下表中詳細解釋。

序號 萬用字元 & 描述
1

百分號 (%)

匹配一個或多個字元。

注意 - MS Access 使用星號 (*) 萬用字元而不是百分號 (%) 萬用字元。

2

下劃線 (_)

匹配一個字元。

注意 - MS Access 使用問號 (?) 代替下劃線 (_) 來匹配任何一個字元。

百分號表示零個、一個或多個字元。下劃線表示單個數字或字元。這些符號可以組合使用。

語法

“%”和“_”運算子的基本語法如下所示。

SELECT * FROM table_name
WHERE column LIKE 'XXXX%'

or 

SELECT * FROM table_name
WHERE column LIKE '%XXXX%'

or

SELECT * FROM table_name
WHERE column LIKE 'XXXX_'

or

SELECT * FROM table_name
WHERE column LIKE '_XXXX'

or

SELECT * FROM table_name
WHERE column LIKE '_XXXX_'

您可以使用 AND 或 OR 運算子組合 N 個條件。這裡,XXXX 可以是任何數字或字串值。

示例

下表包含一些示例,其中 WHERE 部分具有不同的 LIKE 子句以及“%”和“_”運算子。

序號 語句 & 描述
1

WHERE SALARY LIKE '200%'

查詢以 200 開頭的任何值。

2

WHERE SALARY LIKE '%200%'

查詢在任何位置包含 200 的任何值。

3

WHERE SALARY LIKE '_00%'

查詢在第二個和第三個位置包含 00 的任何值。

4

WHERE SALARY LIKE '2_%_%'

查詢以 2 開頭且至少包含 3 個字元的任何值。

5

WHERE SALARY LIKE '%2'

查詢以 2 結尾的任何值。

6

WHERE SALARY LIKE '_2%3'

查詢在第二個位置包含 2 且以 3 結尾的任何值。

7

WHERE SALARY LIKE '2___3'

查詢五位數中以 2 開頭並以 3 結尾的任何值。

讓我們舉一個真實的例子,假設 CUSTOMERS 表具有以下記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下程式碼塊是一個示例,它將顯示 CUSTOMERS 表中所有 SALARY 以 200 開頭的記錄。

SQL> SELECT * FROM CUSTOMERS
WHERE SALARY LIKE '200%';

這將產生以下結果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
+----+----------+-----+-----------+----------+

SQL - 日期函式

下表列出了透過 SQL 可用的所有重要日期和時間相關函式。您的 RDBMS 支援各種其他函式。給定列表基於 MySQL RDBMS。

序號 函式 & 描述
1 ADDDATE()

新增日期

2 ADDTIME()

新增時間

3 CONVERT_TZ()

從一個時區轉換為另一個時區

4 CURDATE()

返回當前日期

5 CURRENT_DATE(),CURRENT_DATE

CURDATE() 的同義詞

6 CURRENT_TIME(),CURRENT_TIME

CURTIME() 的同義詞

7 CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP

NOW() 的同義詞

8 CURTIME()

返回當前時間

9 DATE_ADD()

新增兩個日期

10 DATE_FORMAT()

按照指定格式化日期

11 DATE_SUB()

減去兩個日期

12 DATE()

提取日期或日期時間表達式的日期部分

13 DATEDIFF()

減去兩個日期

14 DAY()

DAYOFMONTH() 的同義詞

15 DAYNAME()

返回星期的名稱

16 DAYOFMONTH()

返回月份中的日期 (1-31)

17 DAYOFWEEK()

返回引數的星期索引

18 DAYOFYEAR()

返回一年中的日期 (1-366)

19 EXTRACT

提取日期的一部分

20 FROM_DAYS()

將日期編號轉換為日期

21 FROM_UNIXTIME()

將日期格式化為 UNIX 時間戳

22 HOUR()

提取小時

23 LAST_DAY

返回引數的月份的最後一天

24 LOCALTIME(),LOCALTIME

NOW() 的同義詞

25 LOCALTIMESTAMP,LOCALTIMESTAMP()

NOW() 的同義詞

26 MAKEDATE()

根據年份和一年中的日期建立日期

27 MAKETIME

MAKETIME()

28 MICROSECOND()

返回引數的微秒數

29 MINUTE()

返回引數的分鐘數

30 MONTH()

返回傳遞的日期的月份

31 MONTHNAME()

返回月份的名稱

32 NOW()

返回當前日期和時間

33 PERIOD_ADD()

將期間新增到年-月

34 PERIOD_DIFF()

返回期間之間的月數

35 QUARTER()

返回日期引數的季度

36 SEC_TO_TIME()

將秒轉換為“HH:MM:SS”格式

37 SECOND()

返回秒數 (0-59)

38 STR_TO_DATE()

將字串轉換為日期

39 SUBDATE()

當使用三個引數呼叫時,SUBDATE() 是 DATE_SUB() 的同義詞

40 SUBTIME()

減去時間

41 SYSDATE()

返回函式執行的時間

42 TIME_FORMAT()

格式化為時間

43 TIME_TO_SEC()

返回轉換為秒的引數

44 TIME()

提取傳遞的表示式的時段部分

45 TIMEDIFF()

減去時間

46 TIMESTAMP()

如果只有一個引數,此函式將返回日期或日期時間表達式。如果有兩個引數,則返回引數的和

47 TIMESTAMPADD()

將間隔新增到日期時間表達式

48 TIMESTAMPDIFF()

從日期時間表達式中減去一個間隔

49 TO_DAYS()

返回轉換為天的日期引數

50 UNIX_TIMESTAMP()

返回 UNIX 時間戳

51 UTC_DATE()

返回當前 UTC 日期

52 UTC_TIME()

返回當前 UTC 時間

53 UTC_TIMESTAMP()

返回當前 UTC 日期和時間

54 WEEK()

返回星期數

55 WEEKDAY()

返回星期索引

56 WEEKOFYEAR()

返回日期的日曆周 (1-53)

57 YEAR()

返回年份

58 YEARWEEK()

返回年份和星期

ADDDATE(date,INTERVAL expr unit), ADDDATE(expr,days)

當使用第二個引數的 INTERVAL 形式呼叫時,ADDDATE() 是 DATE_ADD() 的同義詞。相關函式 SUBDATE() 是 DATE_SUB() 的同義詞。有關 INTERVAL unit 引數的資訊,請參閱 DATE_ADD() 的討論。

mysql> SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| DATE_ADD('1998-01-02', INTERVAL 31 DAY)                 |
+---------------------------------------------------------+
| 1998-02-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT ADDDATE('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| ADDDATE('1998-01-02', INTERVAL 31 DAY)                  |
+---------------------------------------------------------+
| 1998-02-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

當使用第二個引數的 days 形式呼叫時,MySQL 將其視為要新增到 expr 的整數天數。

mysql> SELECT ADDDATE('1998-01-02', 31);
+---------------------------------------------------------+
| DATE_ADD('1998-01-02', INTERVAL 31 DAY)                 |
+---------------------------------------------------------+
| 1998-02-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

ADDTIME(expr1,expr2)

ADDTIME() 將 expr2 新增到 expr1 並返回結果。expr1 是時間或日期時間表達式,而 expr2 是時間表達式。

mysql> SELECT ADDTIME('1997-12-31 23:59:59.999999','1 1:1:1.000002');
+---------------------------------------------------------+
| DATE_ADD('1997-12-31 23:59:59.999999','1 1:1:1.000002') |
+---------------------------------------------------------+
| 1998-01-02 01:01:01.000001                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CONVERT_TZ(dt,from_tz,to_tz)

這會將日期時間值 dt 從 from_tz 給定的時區轉換為 to_tz 給定的時區,並返回結果值。如果引數無效,此函式將返回 NULL。

mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
+---------------------------------------------------------+
| CONVERT_TZ('2004-01-01 12:00:00','GMT','MET')           |
+---------------------------------------------------------+
| 2004-01-01 13:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
+---------------------------------------------------------+
| CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00')     |
+---------------------------------------------------------+
| 2004-01-01 22:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CURDATE()

返回當前日期,格式為“YYYY-MM-DD”或 YYYYMMDD,具體取決於函式是在字串中使用還是在數字上下文中使用。

mysql> SELECT CURDATE();
+---------------------------------------------------------+
| CURDATE()                                               |
+---------------------------------------------------------+
| 1997-12-15                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT CURDATE() + 0;
+---------------------------------------------------------+
| CURDATE() + 0                                           |
+---------------------------------------------------------+
| 19971215                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CURRENT_DATE 和 CURRENT_DATE()

CURRENT_DATE 和 CURRENT_DATE() 是 CURDATE() 的同義詞

CURTIME()

返回當前時間,格式為“HH:MM:SS”或 HHMMSS,具體取決於函式是在字串中使用還是在數字上下文中使用。該值以當前時區表示。

mysql> SELECT CURTIME();
+---------------------------------------------------------+
| CURTIME()                                               |
+---------------------------------------------------------+
| 23:50:26                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT CURTIME() + 0;
+---------------------------------------------------------+
| CURTIME() + 0                                           |
+---------------------------------------------------------+
| 235026                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CURRENT_TIME 和 CURRENT_TIME()

CURRENT_TIME 和 CURRENT_TIME() 是 CURTIME() 的同義詞。

CURRENT_TIMESTAMP 和 CURRENT_TIMESTAMP()

CURRENT_TIMESTAMP 和 CURRENT_TIMESTAMP() 是 NOW() 的同義詞。

DATE(expr)

提取日期或日期時間表達式 expr 的日期部分。

mysql> SELECT DATE('2003-12-31 01:02:03');
+---------------------------------------------------------+
| DATE('2003-12-31 01:02:03')                             |
+---------------------------------------------------------+
|  2003-12-31                                             |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATEDIFF(expr1,expr2)

DATEDIFF() 返回 expr1 - expr2,表示從一個日期到另一個日期的天數。expr1 和 expr2 都是日期或日期和時間表達式。計算中僅使用值的日期部分。

mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
+---------------------------------------------------------+
| DATEDIFF('1997-12-31 23:59:59','1997-12-30')            |
+---------------------------------------------------------+
| 1                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATE_ADD(date,INTERVAL expr unit), DATE_SUB(date,INTERVAL expr unit)

這些函式執行日期運算。date 是指定起始日期的 DATETIME 或 DATE 值。expr 是一個表示式,指定要新增到或從起始日期中減去的間隔值。expr 是一個字串;它可以以“-”開頭表示負間隔。

unit 是一個關鍵字,指示應如何解釋表示式中的單位。

INTERVAL 關鍵字和 unit 說明符不區分大小寫。

下表顯示了每個 unit 值的 expr 引數的預期格式。

unit 值 預期 expr 格式
MICROSECOND MICROSECONDS
SECOND SECONDS
分鐘 分鐘
小時 小時
季度 季度
秒和微秒 '秒.微秒'
分鐘和微秒 '分鐘.微秒'
分鐘和秒 '分鐘:秒'
小時和微秒 '小時.微秒'
小時、分鐘和秒 '小時:分鐘:秒'
小時和分鐘 '小時:分鐘'
天和微秒 '天.微秒'
天、小時、分鐘和秒 '天 小時:分鐘:秒'
天、小時和分鐘 '天 小時:分鐘'
天和小時 '天 小時'
年和月 '年-月'

從 MySQL 5.0.0 版本開始提供季度的值。

mysql> SELECT DATE_ADD('1997-12-31 23:59:59', 
   -> INTERVAL '1:1' MINUTE_SECOND);
+---------------------------------------------------------+
| DATE_ADD('1997-12-31 23:59:59', INTERVAL...             |
+---------------------------------------------------------+
| 1998-01-01 00:01:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
+---------------------------------------------------------+
| DATE_ADD('1999-01-01', INTERVAL 1 HOUR)                 |
+---------------------------------------------------------+
| 1999-01-01 01:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATE_FORMAT(日期,格式)

此命令根據格式字串格式化日期值。

格式字串中可以使用以下說明符。格式說明符字元前需要使用“%”字元。

序號說明符 & 描述
1

%a

縮寫星期名稱 (Sun..Sat)

2

%b

縮寫月份名稱 (Jan..Dec)

3

%c

月份,數字 (0..12)

4

%D

帶英文字尾的月份日期 (0th, 1st, 2nd, 3rd, .)

5

%d

月份日期,數字 (00..31)

6

%e

月份日期,數字 (0..31)

7

%f

微秒 (000000..999999)

8

%H

小時 (00..23)

9

%h

小時 (01..12)

10

%I

小時 (01..12)

11

%i

分鐘,數字 (00..59)

12

%j

一年中的第幾天 (001..366)

13

%k

小時 (0..23)

14

%l

小時 (1..12)

15

%M

月份名稱 (January..December)

16

%m

月份,數字 (00..12)

17

%p

AM 或 PM

18

%r

12 小時制時間 (hh:mm:ss 後跟 AM 或 PM)

19

%S

秒 (00..59)

20

%s

秒 (00..59)

21

%T

24 小時制時間 (hh:mm:ss)

22

%U

星期 (00..53),其中星期日是星期中的第一天

23

%u

星期 (00..53),其中星期一是星期中的第一天

24

%V

星期 (01..53),其中星期日是星期中的第一天;與 %X 一起使用

25

%v

星期 (01..53),其中星期一是星期中的第一天;與 %x 一起使用

26

%W

星期名稱 (Sunday..Saturday)

27

%w

星期中的第幾天 (0=星期日..6=星期六)

28

%X

星期所在的年份,其中星期日是星期中的第一天,數字,四位數字;與 %V 一起使用

29

%x

星期所在的年份,其中星期一是星期中的第一天,數字,四位數字;與 %v 一起使用

30

%Y

年份,數字,四位數字

31

%y

年份,數字 (兩位數字)

32

%%

字面值 .%. 字元

33

%x

x,對於上面未列出的任何 .x.

mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
+---------------------------------------------------------+
| DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y')          |
+---------------------------------------------------------+
| Saturday October 1997                                   |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00'
   -> '%H %k %I %r %T %S %w');
+---------------------------------------------------------+
| DATE_FORMAT('1997-10-04 22:23:00.......                 |
+---------------------------------------------------------+
|  22 22 10 10:23:00 PM 22:23:00 00 6                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATE_SUB(日期,INTERVAL 表示式 單位)

這與 DATE_ADD() 函式類似。

DAY(日期)

DAY() 是 DAYOFMONTH() 函式的同義詞。

DAYNAME(日期)

返回日期的星期名稱。

mysql> SELECT DAYNAME('1998-02-05');
+---------------------------------------------------------+
| DAYNAME('1998-02-05')                                   |
+---------------------------------------------------------+
| Thursday                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DAYOFMONTH(日期)

返回日期的月份日期,範圍為 0 到 31。

mysql> SELECT DAYOFMONTH('1998-02-03');
+---------------------------------------------------------+
| DAYOFMONTH('1998-02-03')                                |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DAYOFWEEK(日期)

返回日期的星期索引 (1 = 星期日,2 = 星期一,...,7 = 星期六)。這些索引值對應於 ODBC 標準。

mysql> SELECT DAYOFWEEK('1998-02-03');
+---------------------------------------------------------+
|DAYOFWEEK('1998-02-03')                                  |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DAYOFYEAR(日期)

返回日期的一年中的第幾天,範圍為 1 到 366。

mysql> SELECT DAYOFYEAR('1998-02-03');
+---------------------------------------------------------+
| DAYOFYEAR('1998-02-03')                                 |
+---------------------------------------------------------+
| 34                                                      |
+---------------------------------------------------------+
1 row in set (0.00 sec)

EXTRACT(單位 FROM 日期)

EXTRACT() 函式使用與 DATE_ADD() 或 DATE_SUB() 相同型別的單位說明符,但從日期中提取部分而不是執行日期運算。

mysql> SELECT EXTRACT(YEAR FROM '1999-07-02');
+---------------------------------------------------------+
| EXTRACT(YEAR FROM '1999-07-02')                         |
+---------------------------------------------------------+
| 1999                                                    |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03');
+---------------------------------------------------------+
| EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03')          |
+---------------------------------------------------------+
| 199907                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

FROM_DAYS(N)

給定一個日期編號 N,返回一個 DATE 值。

mysql> SELECT FROM_DAYS(729669);
+---------------------------------------------------------+
| FROM_DAYS(729669)                                       |
+---------------------------------------------------------+
| 1997-10-07                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

注意 - 在舊日期上謹慎使用 FROM_DAYS()。它不適用于格裡歷出現之前的日期值 (1582)。

FROM_UNIXTIME(unix 時間戳)

FROM_UNIXTIME(unix 時間戳,格式)

返回unix 時間戳引數的表示形式,作為“YYYY-MM-DD HH:MM:SS 或 YYYYMMDDHHMMSS 格式的值,具體取決於函式是在字串中還是在數字上下文中使用。該值以當前時區表示。unix 時間戳引數是內部時間戳值,由UNIX_TIMESTAMP() 函式生成。

如果給定了格式,則結果將根據格式字串進行格式化,格式字串的使用方式與DATE_FORMAT() 函式條目中列出的一樣。

mysql> SELECT FROM_UNIXTIME(875996580);
+---------------------------------------------------------+
| FROM_UNIXTIME(875996580)                                |
+---------------------------------------------------------+
| 1997-10-04 22:23:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

HOUR(時間)

返回時間的小時。對於一天中的時間值,返回值的範圍為 0 到 23。但是,TIME 值的範圍實際上要大得多,因此 HOUR 可以返回大於 23 的值。

mysql> SELECT HOUR('10:05:03');
+---------------------------------------------------------+
| HOUR('10:05:03')                                        |
+---------------------------------------------------------+
| 10                                                      |
+---------------------------------------------------------+
1 row in set (0.00 sec)

LAST_DAY(日期)

獲取日期或日期時間值並返回對應月份的最後一天的值。如果引數無效,則返回 NULL。

mysql> SELECT LAST_DAY('2003-02-05');
+---------------------------------------------------------+
| LAST_DAY('2003-02-05')                                  |
+---------------------------------------------------------+
| 2003-02-28                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

LOCALTIME 和 LOCALTIME()

LOCALTIME 和 LOCALTIME() 是 NOW() 的同義詞。

LOCALTIMESTAMP 和 LOCALTIMESTAMP()

LOCALTIMESTAMP 和 LOCALTIMESTAMP() 是 NOW() 的同義詞。

MAKEDATE(年份,一年中的第幾天)

給定年份和一年中的第幾天值,返回一個日期。一年中的第幾天值必須大於 0,否則結果將為 NULL。

mysql> SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
+---------------------------------------------------------+
| MAKEDATE(2001,31), MAKEDATE(2001,32)                    |
+---------------------------------------------------------+
| '2001-01-31', '2001-02-01'                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MAKETIME(小時,分鐘,秒)

根據小時、分鐘和秒引數返回一個時間值。

mysql> SELECT MAKETIME(12,15,30);
+---------------------------------------------------------+
| MAKETIME(12,15,30)                                      |
+---------------------------------------------------------+
| '12:15:30'                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MICROSECOND(表示式)

從時間或日期時間表達式 (表示式) 中返回微秒,作為 0 到 999999 範圍內的數字。

mysql> SELECT MICROSECOND('12:00:00.123456');
+---------------------------------------------------------+
| MICROSECOND('12:00:00.123456')                          |
+---------------------------------------------------------+
| 123456                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MINUTE(時間)

返回時間的分,範圍為 0 到 59。

mysql> SELECT MINUTE('98-02-03 10:05:03');
+---------------------------------------------------------+
| MINUTE('98-02-03 10:05:03')                             |
+---------------------------------------------------------+
| 5                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MONTH(日期)

返回日期的月份,範圍為 0 到 12。

mysql> SELECT MONTH('1998-02-03')
+---------------------------------------------------------+
| MONTH('1998-02-03')                                     |
+---------------------------------------------------------+
| 2                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MONTHNAME(日期)

返回日期的月份的全稱。

mysql> SELECT MONTHNAME('1998-02-05');
+---------------------------------------------------------+
| MONTHNAME('1998-02-05')                                 |
+---------------------------------------------------------+
| February                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

NOW()

返回當前日期和時間,作為“YYYY-MM-DD HH:MM:SS”或 YYYYMMDDHHMMSS 格式的值,具體取決於函式是在字串中還是在數字上下文中使用。此值以當前時區表示。

mysql> SELECT NOW();
+---------------------------------------------------------+
| NOW()                                                   |
+---------------------------------------------------------+
| 1997-12-15 23:50:26                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

PERIOD_ADD(P,N)

向期間 P (格式為 YYMM 或 YYYYMM) 新增 N 個月。返回 YYYYMM 格式的值。請注意,期間引數 P 不是日期值。

mysql> SELECT PERIOD_ADD(9801,2);
+---------------------------------------------------------+
| PERIOD_ADD(9801,2)                                      |
+---------------------------------------------------------+
| 199803                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

PERIOD_DIFF(P1,P2)

返回期間 P1 和 P2 之間的月數。這些期間 P1 和 P2 應為 YYMM 或 YYYYMM 格式。請注意,期間引數 P1 和 P2 不是日期值。

mysql> SELECT PERIOD_DIFF(9802,199703);
+---------------------------------------------------------+
| PERIOD_DIFF(9802,199703)                                |
+---------------------------------------------------------+
| 11                                                      |
+---------------------------------------------------------+
1 row in set (0.00 sec)

QUARTER(日期)

返回日期所在年份的季度,範圍為 1 到 4。

mysql> SELECT QUARTER('98-04-01');
+---------------------------------------------------------+
| QUARTER('98-04-01')                                     |
+---------------------------------------------------------+
| 2                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SECOND(時間)

返回時間秒,範圍為 0 到 59。

mysql> SELECT SECOND('10:05:03');
+---------------------------------------------------------+
| SECOND('10:05:03')                                      |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SEC_TO_TIME(秒)

返回秒引數,轉換為小時、分鐘和秒,作為“HH:MM:SS”或 HHMMSS 格式的值,具體取決於函式是在字串中還是在數字上下文中使用。

mysql> SELECT SEC_TO_TIME(2378);
+---------------------------------------------------------+
| SEC_TO_TIME(2378)                                       |
+---------------------------------------------------------+
| 00:39:38                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

STR_TO_DATE(字串,格式)

這是 DATE_FORMAT() 函式的反函式。它獲取一個字串 str 和一個格式字串 format。如果格式字元串同時包含日期和時間部分,則 STR_TO_DATE() 函式返回一個 DATETIME 值。否則,如果字串僅包含日期或時間部分,則返回 DATE 或 TIME 值。

mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
+---------------------------------------------------------+
| STR_TO_DATE('04/31/2004', '%m/%d/%Y')                   |
+---------------------------------------------------------+
| 2004-04-31                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SUBDATE(日期,INTERVAL 表示式 單位) 和 SUBDATE(表示式,天)

當使用第二個引數的 INTERVAL 形式呼叫時,SUBDATE() 是 DATE_SUB() 的同義詞。有關 INTERVAL 單位引數的資訊,請參閱 DATE_ADD() 的討論。

mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| DATE_SUB('1998-01-02', INTERVAL 31 DAY)                 |
+---------------------------------------------------------+
| 1997-12-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT SUBDATE('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| SUBDATE('1998-01-02', INTERVAL 31 DAY)                  |
+---------------------------------------------------------+
| 1997-12-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SUBTIME(表示式1,表示式2)

SUBTIME() 函式返回表示式1 - 表示式2,表示為與表示式1 相同格式的值。表示式1 值是時間或日期時間表達式,而表示式2 值是時間表達式。

mysql> SELECT SUBTIME('1997-12-31 23:59:59.999999',
   -> '1 1:1:1.000002');
+---------------------------------------------------------+
| SUBTIME('1997-12-31 23:59:59.999999'...                 |
+---------------------------------------------------------+
| 1997-12-30 22:58:58.999997                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SYSDATE()

返回當前日期和時間,作為“YYYY-MM-DD HH:MM:SS”或 YYYYMMDDHHMMSS 格式的值,具體取決於函式是在字串中還是在數字上下文中使用。

mysql> SELECT SYSDATE();
+---------------------------------------------------------+
| SYSDATE()                                               |
+---------------------------------------------------------+
| 2006-04-12 13:47:44                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIME(表示式)

提取時間或日期時間表達式表示式的時間部分並將其作為字串返回。

mysql> SELECT TIME('2003-12-31 01:02:03');
+---------------------------------------------------------+
| TIME('2003-12-31 01:02:03')                             |
+---------------------------------------------------------+
| 01:02:03                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMEDIFF(表示式1,表示式2)

TIMEDIFF() 函式返回表示式1 - 表示式2,表示為時間值。這些表示式1 和表示式2 值是時間或日期時間表達式,但兩者必須為同一型別。

mysql> SELECT TIMEDIFF('1997-12-31 23:59:59.000001',
   -> '1997-12-30 01:01:01.000002');
+---------------------------------------------------------+
| TIMEDIFF('1997-12-31 23:59:59.000001'.....              |
+---------------------------------------------------------+
|  46:58:57.999999                                        |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMESTAMP(表示式), TIMESTAMP(表示式1,表示式2)

使用單個引數時,此函式將日期或日期時間表達式表示式作為日期時間值返回。使用兩個引數時,它將時間表達式表示式2 新增到日期或日期時間表達式表示式1 並將結果作為日期時間值返回。

mysql> SELECT TIMESTAMP('2003-12-31');
+---------------------------------------------------------+
| TIMESTAMP('2003-12-31')                                 |
+---------------------------------------------------------+
| 2003-12-31 00:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMESTAMPADD(單位,間隔,日期時間表達式)

此函式將整數表示式間隔新增到日期或日期時間表達式日期時間表達式。間隔的單位由單位引數給出,該引數應為以下值之一 -

  • FRAC_SECOND
  • SECOND, MINUTE
  • HOUR, DAY
  • QUARTER 或

單位值可以使用所示的關鍵字之一或使用 SQL_TSI_ 字首指定。

例如,DAY 和 SQL_TSI_DAY 都是合法的。

mysql> SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
+---------------------------------------------------------+
| TIMESTAMPADD(MINUTE,1,'2003-01-02')                     |
+---------------------------------------------------------+
| 2003-01-02 00:01:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMESTAMPDIFF(單位,日期時間表達式1,日期時間表達式2)

返回日期或日期時間表達式日期時間表達式1 和日期時間表達式2 之間的整數差。結果的單位由單位引數給出。單位的合法值與 TIMESTAMPADD() 函式說明中列出的值相同。

mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
+---------------------------------------------------------+
| TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01')          |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIME_FORMAT(時間,格式)

此函式的使用方式類似於 DATE_FORMAT() 函式,但格式字串只能包含小時、分鐘和秒的格式說明符。

如果時間值包含大於 23 的小時部分,則 %H 和 %k 小時格式說明符會生成大於 0 到 23 的通常範圍的值。其他小時格式說明符生成小時值模 12。

mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
+---------------------------------------------------------+
| TIME_FORMAT('100:00:00', '%H %k %h %I %l')              |
+---------------------------------------------------------+
| 100 100 04 04 4                                         |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIME_TO_SEC(時間)

返回轉換為秒的時間引數。

mysql> SELECT TIME_TO_SEC('22:23:00');
+---------------------------------------------------------+
| TIME_TO_SEC('22:23:00')                                 |
+---------------------------------------------------------+
| 80580                                                   |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TO_DAYS(日期)

給定一個日期,返回一個日期編號 (自公元 0 年以來的天數)。

mysql> SELECT TO_DAYS(950501);
+---------------------------------------------------------+
| TO_DAYS(950501)                                         |
+---------------------------------------------------------+
| 728779                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UNIX_TIMESTAMP(), UNIX_TIMESTAMP(日期)

如果未帶引數呼叫,則此函式返回一個 Unix 時間戳 (自“1970-01-01 00:00:00”UTC 以來經過的秒數) 作為無符號整數。如果使用日期引數呼叫 UNIX_TIMESTAMP(),則返回自“1970-01-01 00:00:00”UTC 以來引數的值(以秒為單位)。日期可以是 DATE 字串、DATETIME 字串、TIMESTAMP 或 YYMMDD 或 YYYYMMDD 格式的數字。

mysql> SELECT UNIX_TIMESTAMP();
+---------------------------------------------------------+
| UNIX_TIMESTAMP()                                        |
+---------------------------------------------------------+
| 882226357                                               |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
+---------------------------------------------------------+
| UNIX_TIMESTAMP('1997-10-04 22:23:00')                   |
+---------------------------------------------------------+
| 875996580                                               |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UTC_DATE, UTC_DATE()

返回當前 UTC 日期,作為“YYYY-MM-DD”或 YYYYMMDD 格式的值,具體取決於函式是在字串中還是在數字上下文中使用。

mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
+---------------------------------------------------------+
| UTC_DATE(), UTC_DATE() + 0                              |
+---------------------------------------------------------+
| 2003-08-14, 20030814                                    |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UTC_TIME, UTC_TIME()

返回當前 UTC 時間,作為“HH:MM:SS”或 HHMMSS 格式的值,具體取決於函式是在字串中還是在數字上下文中使用。

mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
+---------------------------------------------------------+
| UTC_TIME(), UTC_TIME() + 0                              |
+---------------------------------------------------------+
| 18:07:53, 180753                                        |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UTC_TIMESTAMP, UTC_TIMESTAMP()

返回當前 UTC 日期和時間,作為“YYYY-MM-DD HH:MM:SS”或 YYYYMMDDHHMMSS 格式的值,具體取決於函式是在字串中還是在數字上下文中使用。

mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
+---------------------------------------------------------+
| UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0                    |
+---------------------------------------------------------+
| 2003-08-14 18:08:04, 20030814180804                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

WEEK(日期[,模式])

此函式返回日期的星期數。WEEK() 的雙引數形式允許您指定星期是否從星期日或星期一開始,以及返回值是否應在 0 到 53 或 1 到 53 的範圍內。如果省略 mode 引數,則使用 default_week_format 系統變數的值。

模式 一週的第一天 範圍 第 1 周是第一週。
0 星期日 0-53 今年包含一個星期日
1 星期一 0-53 今年有超過 3 天
2 星期日 1-53 今年包含一個星期日
3 星期一 1-53 今年有超過 3 天
4 星期日 0-53 今年有超過 3 天
5 星期一 0-53 今年包含一個星期一
6 星期日 1-53 今年有超過 3 天
7 星期一 1-53 今年包含一個星期一
mysql> SELECT WEEK('1998-02-20');
+---------------------------------------------------------+
| WEEK('1998-02-20')                                      |
+---------------------------------------------------------+
| 7                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

WEEKDAY(date)

返回日期的星期幾索引(0 = 星期一,1 = 星期二,... 6 = 星期日)。

mysql> SELECT WEEKDAY('1998-02-03 22:23:00');
+---------------------------------------------------------+
| WEEKDAY('1998-02-03 22:23:00')                          |
+---------------------------------------------------------+
| 1                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

WEEKOFYEAR(date)

將日期的日曆周作為 1 到 53 範圍內的數字返回。WEEKOFYEAR() 是一個相容性函式,等效於 WEEK(date,3)。

mysql> SELECT WEEKOFYEAR('1998-02-20');
+---------------------------------------------------------+
| WEEKOFYEAR('1998-02-20')                                |
+---------------------------------------------------------+
| 8                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

YEAR(date)

返回日期的年份,範圍為 1000 到 9999,或 0 表示零日期。

mysql> SELECT YEAR('98-02-03');
+---------------------------------------------------------+
| YEAR('98-02-03')                                        |
+---------------------------------------------------------+
| 1998                                                    |
+---------------------------------------------------------+
1 row in set (0.00 sec)

YEARWEEK(date), YEARWEEK(date,mode)

返回日期的年份和星期數。mode 引數的工作方式與 WEEK() 函式的 mode 引數完全相同。對於一年中的第一週和最後一週,結果中的年份可能與日期引數中的年份不同。

mysql> SELECT YEARWEEK('1987-01-01');
+---------------------------------------------------------+
| YEAR('98-02-03')YEARWEEK('1987-01-01')                  |
+---------------------------------------------------------+
| 198653                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

注意 - 對於可選引數 0 或 1,星期數與 WEEK() 函式返回的值(0)不同,因為 WEEK() 然後在給定年份的上下文中返回星期數。

SQL - 臨時表

什麼是臨時表?

有一些 RDBMS 支援臨時表。臨時表是一個很棒的功能,它允許您儲存和處理中間結果,方法是使用與典型 SQL Server 表相同的選擇、更新和連線功能。

臨時表在某些情況下可能非常有用,可以儲存臨時資料。關於臨時表應該知道的最重要的一點是,噹噹前客戶端會話終止時,它們將被刪除。

MySQL 3.23 及更高版本中提供了臨時表。如果您使用的 MySQL 版本早於 3.23,則無法使用臨時表,但可以使用堆表

如前所述,臨時表僅在會話處於活動狀態時才會存在。如果您在 PHP 指令碼中執行程式碼,則指令碼執行完成後,臨時表將自動銷燬。如果您透過 MySQL 客戶端程式連線到 MySQL 資料庫伺服器,則臨時表將一直存在,直到您關閉客戶端或手動銷燬該表。

示例

以下是一個顯示臨時表用法的示例。

mysql> CREATE TEMPORARY TABLE SALESSUMMARY (
   -> product_name VARCHAR(50) NOT NULL
   -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
   -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
   -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SALESSUMMARY
   -> (product_name, total_sales, avg_unit_price, total_units_sold)
   -> VALUES
   -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SALESSUMMARY;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)

當您發出 SHOW TABLES 命令時,您的臨時表將不會在列表中列出。現在,如果您退出 MySQL 會話,然後發出 SELECT 命令,您會發現資料庫中沒有可用資料。甚至您的臨時表也將不存在。

刪除臨時表

預設情況下,當您的資料庫連線終止時,所有臨時表都將由 MySQL 刪除。如果您想在中途刪除它們,則可以透過發出DROP TABLE 命令來實現。

以下是刪除臨時表的示例。

mysql> CREATE TEMPORARY TABLE SALESSUMMARY (
   -> product_name VARCHAR(50) NOT NULL
   -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
   -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
   -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SALESSUMMARY
   -> (product_name, total_sales, avg_unit_price, total_units_sold)
   -> VALUES
   -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SALESSUMMARY;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)
mysql> DROP TABLE SALESSUMMARY;
mysql>  SELECT * FROM SALESSUMMARY;
ERROR 1146: Table 'TUTORIALS.SALESSUMMARY' doesn't exist

SQL - 克隆表

可能存在需要表的確切副本的情況,而 CREATE TABLE ... 或 SELECT... 命令不適合您的目的,因為副本必須包含相同的索引、預設值等。

如果您使用的是 MySQL RDBMS,則可以透過遵循以下步驟來處理這種情況:

  • 使用 SHOW CREATE TABLE 命令獲取指定源表結構、索引等的 CREATE TABLE 語句。

  • 修改該語句以將表名更改為克隆表的表名,並執行該語句。這樣,您將擁有一個完全克隆的表。

  • 可選地,如果您還需要複製表內容,則也發出 INSERT INTO 或 SELECT 語句。

示例

嘗試以下示例為TUTORIALS_TBL 建立一個克隆表,其結構如下:

步驟 1 - 獲取有關表的完整結構。

SQL> SHOW CREATE TABLE TUTORIALS_TBL \G; 
*************************** 1. row *************************** 
      Table: TUTORIALS_TBL 
Create Table: CREATE TABLE 'TUTORIALS_TBL' ( 
  'tutorial_id' int(11) NOT NULL auto_increment, 
  'tutorial_title' varchar(100) NOT NULL default '', 
  'tutorial_author' varchar(40) NOT NULL default '', 
  'submission_date' date default NULL, 
  PRIMARY KEY  ('tutorial_id'), 
  UNIQUE KEY 'AUTHOR_INDEX' ('tutorial_author') 
) TYPE = MyISAM 
1 row in set (0.00 sec)

步驟 2 - 重新命名此表並建立另一個表。

SQL> CREATE TABLE `CLONE_TBL` ( 
  -> 'tutorial_id' int(11) NOT NULL auto_increment, 
  -> 'tutorial_title' varchar(100) NOT NULL default '', 
  -> 'tutorial_author' varchar(40) NOT NULL default '', 
  -> 'submission_date' date default NULL, 
  -> PRIMARY KEY  (`tutorial_id'), 
  -> UNIQUE KEY 'AUTHOR_INDEX' ('tutorial_author') 
-> ) TYPE = MyISAM; 
Query OK, 0 rows affected (1.80 sec) 

步驟 3 - 執行步驟 2 後,您將在資料庫中克隆一個表。如果您想從舊錶複製資料,則可以使用 INSERT INTO... SELECT 語句。

SQL> INSERT INTO CLONE_TBL (tutorial_id, 
   ->                        tutorial_title, 
   ->                        tutorial_author, 
   ->                        submission_date) 
   -> SELECT tutorial_id,tutorial_title, 
   ->        tutorial_author,submission_date, 
   -> FROM TUTORIALS_TBL; 
Query OK, 3 rows affected (0.07 sec) 
Records: 3  Duplicates: 0  Warnings: 0 

最後,您將獲得您想要的完全克隆表。

SQL - 子查詢

子查詢或內部查詢或巢狀查詢是在另一個 SQL 查詢中的查詢,並嵌入在 WHERE 子句中。

子查詢用於返回將在主查詢中用作條件的資料,以進一步限制要檢索的資料。

子查詢可以與 SELECT、INSERT、UPDATE 和 DELETE 語句以及 =、<、>、>=、<=、IN、BETWEEN 等運算子一起使用。

子查詢必須遵循一些規則:

  • 子查詢必須括在括號中。

  • 子查詢在 SELECT 子句中只能有一列,除非主查詢中有多列供子查詢比較其選定的列。

  • 雖然主查詢可以使用 ORDER BY,但在子查詢中不能使用 ORDER BY 命令。GROUP BY 命令可以用於執行與子查詢中的 ORDER BY 相同的功能。

  • 返回多行的子查詢只能與多值運算子(如 IN 運算子)一起使用。

  • SELECT 列表不能包含任何引用計算結果為 BLOB、ARRAY、CLOB 或 NCLOB 的值的引用。

  • 子查詢不能立即包含在集合函式中。

  • BETWEEN 運算子不能與子查詢一起使用。但是,可以在子查詢中使用 BETWEEN 運算子。

帶有 SELECT 語句的子查詢

子查詢最常與 SELECT 語句一起使用。基本語法如下:

SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
   (SELECT column_name [, column_name ]
   FROM table1 [, table2 ]
   [WHERE])

示例

考慮 CUSTOMERS 表具有以下記錄 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

現在,讓我們檢查以下帶有 SELECT 語句的子查詢。

SQL> SELECT * 
   FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
         FROM CUSTOMERS 
         WHERE SALARY > 4500) ;

這將產生以下結果。

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  5 | Hardik   |  27 | Bhopal  |  8500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+

帶有 INSERT 語句的子查詢

子查詢也可以與 INSERT 語句一起使用。INSERT 語句使用子查詢返回的資料插入到另一個表中。子查詢中選定的資料可以使用任何字元、日期或數字函式進行修改。

基本語法如下。

INSERT INTO table_name [ (column1 [, column2 ]) ]
   SELECT [ *|column1 [, column2 ]
   FROM table1 [, table2 ]
   [ WHERE VALUE OPERATOR ]

示例

假設有一個與 CUSTOMERS 表結構類似的 CUSTOMERS_BKP 表。現在要將完整的 CUSTOMERS 表複製到 CUSTOMERS_BKP 表中,可以使用以下語法。

SQL> INSERT INTO CUSTOMERS_BKP
   SELECT * FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
   FROM CUSTOMERS) ;

帶有 UPDATE 語句的子查詢

子查詢可以與 UPDATE 語句結合使用。使用子查詢與 UPDATE 語句結合時,可以更新表中的單個或多個列。

基本語法如下。

UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

示例

假設我們有 CUSTOMERS_BKP 表可用,它是 CUSTOMERS 表的備份。以下示例將 CUSTOMERS 表中所有年齡大於或等於 27 的客戶的 SALARY 更新為 0.25 倍。

SQL> UPDATE CUSTOMERS
   SET SALARY = SALARY * 0.25
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

這將影響兩行,最後 CUSTOMERS 表將包含以下記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |   125.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  2125.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

帶有 DELETE 語句的子查詢

子查詢可以與 DELETE 語句結合使用,就像上面提到的任何其他語句一樣。

基本語法如下。

DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

示例

假設我們有 CUSTOMERS_BKP 表可用,它是 CUSTOMERS 表的備份。以下示例從 CUSTOMERS 表中刪除所有年齡大於或等於 27 的客戶的記錄。

SQL> DELETE FROM CUSTOMERS
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

這將影響兩行,最後 CUSTOMERS 表將包含以下記錄。

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  2 | Khilan   |  25 | Delhi   |  1500.00 |
|  3 | kaushik  |  23 | Kota    |  2000.00 |
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  6 | Komal    |  22 | MP      |  4500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+

SQL - 使用序列

序列是一組整數 1、2、3、...,它們按需按順序生成。序列在資料庫中經常使用,因為許多應用程式要求表中的每一行都包含一個唯一值,而序列提供了一種生成它們的方法。

本章介紹如何在 MySQL 中使用序列。

使用 AUTO_INCREMENT 列

在 MySQL 中使用序列的最簡單方法是將列定義為 AUTO_INCREMENT,並將其餘操作留給 MySQL 處理。

示例

嘗試以下示例。這將建立一個表,然後在此表中插入幾行,其中不需要提供記錄 ID,因為它是 MySQL 自動遞增的。

mysql> CREATE TABLE INSECT
   -> (
   -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
   -> PRIMARY KEY (id),
   -> name VARCHAR(30) NOT NULL, # type of insect
   -> date DATE NOT NULL, # date collected
   -> origin VARCHAR(30) NOT NULL # where collected
);
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO INSECT (id,name,date,origin) VALUES
   -> (NULL,'housefly','2001-09-10','kitchen'),
   -> (NULL,'millipede','2001-09-10','driveway'),
   -> (NULL,'grasshopper','2001-09-10','front yard');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> SELECT * FROM INSECT ORDER BY id;
+----+-------------+------------+------------+
| id | name        | date       | origin     |
+----+-------------+------------+------------+
|  1 | housefly    | 2001-09-10 | kitchen    |
|  2 | millipede   | 2001-09-10 | driveway   |
|  3 | grasshopper | 2001-09-10 | front yard |
+----+-------------+------------+------------+
3 rows in set (0.00 sec)

獲取 AUTO_INCREMENT 值

LAST_INSERT_ID( ) 是一個 SQL 函式,因此您可以在任何瞭解如何發出 SQL 語句的客戶端中使用它。否則,PERL 和 PHP 指令碼提供了檢索最後一條記錄的自動遞增值的專屬函式。

PERL 示例

使用mysql_insertid 屬性獲取查詢生成的 AUTO_INCREMENT 值。此屬性可以透過資料庫控制代碼或語句控制代碼訪問,具體取決於您發出查詢的方式。以下示例透過資料庫控制代碼引用它。

$dbh->do ("INSERT INTO INSECT (name,date,origin)
VALUES('moth','2001-09-14','windowsill')");
my $seq = $dbh->{mysql_insertid};

PHP 示例

發出生成 AUTO_INCREMENT 值的查詢後,透過呼叫mysql_insert_id( ) 函式檢索該值。

mysql_query ("INSERT INTO INSECT (name,date,origin)
VALUES('moth','2001-09-14','windowsill')", $conn_id);
$seq = mysql_insert_id ($conn_id);

重新編號現有序列

可能存在從表中刪除了許多記錄並且您想重新排序所有記錄的情況。這可以透過使用一個簡單的技巧來完成,但是您應該非常小心地執行此操作,並檢查您的表是否與另一個表具有連線關係。

如果您確定重新排序 AUTO_INCREMENT 列是不可避免的,則執行此操作的方法是從表中刪除該列,然後再次新增它。

以下示例說明如何使用此技術重新編號 insect 表中的 id 值。

mysql> ALTER TABLE INSECT DROP id;
mysql> ALTER TABLE insect
   -> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
   -> ADD PRIMARY KEY (id);

從特定值開始序列

預設情況下,MySQL 將從 1 開始序列,但您也可以在建立表時指定任何其他數字。

以下程式碼塊包含一個示例,其中 MySQL 將從 100 開始序列。

mysql> CREATE TABLE INSECT
   -> (
   -> id INT UNSIGNED NOT NULL AUTO_INCREMENT = 100,
   -> PRIMARY KEY (id),
   -> name VARCHAR(30) NOT NULL, # type of insect
   -> date DATE NOT NULL, # date collected
   -> origin VARCHAR(30) NOT NULL # where collected
);

或者,您可以建立表,然後使用 ALTER TABLE 設定初始序列值。

mysql> ALTER TABLE t AUTO_INCREMENT = 100;

SQL - 處理重複項

可能存在表中有多條重複記錄的情況。在獲取此類記錄時,獲取唯一記錄而不是獲取重複記錄更有意義。

我們已經討論過的 SQLDISTINCT 關鍵字與 SELECT 語句一起使用以消除所有重複記錄,並僅獲取唯一記錄。

語法

消除重複記錄的 DISTINCT 關鍵字的基本語法如下。

SELECT DISTINCT column1, column2,.....columnN 
FROM table_name
WHERE [condition]

示例

假設 CUSTOMERS 表包含以下記錄。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

首先,讓我們看看以下 SELECT 查詢是如何返回重複的工資記錄的。

SQL> SELECT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

這將產生以下結果,其中 2000 的工資出現了兩次,這是原始表中的重複記錄。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

現在,讓我們在上面的 SELECT 查詢中使用 DISTINCT 關鍵字並檢視結果。

SQL> SELECT DISTINCT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

這將產生以下結果,其中我們沒有任何重複條目。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

SQL - 注入

如果您透過網頁獲取使用者輸入並將其插入 SQL 資料庫,則您有可能讓自己面臨一個稱為SQL 注入的安全問題。本章將教您如何幫助防止這種情況發生,並幫助您保護伺服器端指令碼(如 PERL 指令碼)中的指令碼和 SQL 語句。

注入通常發生在您要求使用者輸入資訊(如他們的姓名)時,並且他們給您的不是姓名,而是一個您會在不知情的情況下在資料庫上執行的 SQL 語句。永遠不要信任使用者提供的資料,只有在驗證後才處理這些資料;作為規則,這是透過模式匹配完成的。

在下面的示例中,name 限制為字母數字字元加上下劃線,長度在 8 到 20 個字元之間(根據需要修改這些規則)。

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM CUSTOMERS 
      WHERE name = $matches[0]");
} else {
   echo "user name not accepted";
}

為了演示問題,請考慮以下摘錄:

// supposed input
$name = "Qadir'; DELETE FROM CUSTOMERS;";
mysql_query("SELECT * FROM CUSTOMSRS WHERE name='{$name}'");

函式呼叫應該從 CUSTOMERS 表中檢索一條記錄,其中 name 列與使用者指定的 name 匹配。在正常情況下,$name 只包含字母數字字元以及可能的空間,例如字串 ilia。但是在這裡,透過將一個全新的查詢附加到 $name,對資料庫的呼叫變成了災難;注入的 DELETE 查詢刪除了 CUSTOMERS 表中的所有記錄。

幸運的是,如果您使用 MySQL,mysql_query() 函式不允許查詢堆疊或在單個函式呼叫中執行多個 SQL 查詢。如果您嘗試堆疊查詢,則呼叫會失敗。

但是,其他 PHP 資料庫擴充套件(例如 SQLitePostgreSQL)會愉快地執行堆疊查詢,執行一個字串中提供的所有查詢,並造成嚴重的安全問題。

防止 SQL 注入

您可以在 PERL 和 PHP 等指令碼語言中巧妙地處理所有跳脫字元。PHP 的 MySQL 擴充套件提供了函式 mysql_real_escape_string() 來轉義對 MySQL 具有特殊意義的輸入字元。

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM CUSTOMERS WHERE name='{$name}'");

LIKE 難題

為了解決 LIKE 難題,自定義轉義機制必須將使用者提供的“%”和“_”字元轉換為字面量。使用 addcslashes(),這是一個允許您指定要轉義的字元範圍的函式。

$sub = addcslashes(mysql_real_escape_string("%str"), "%_");
// $sub == \%str\_
mysql_query("SELECT * FROM messages 
   WHERE subject LIKE '{$sub}%'");

SQL - 資料庫調優

成為資料庫專家或專家資料庫管理員需要時間。這都來自於在各種資料庫設計和良好培訓方面的豐富經驗。

但是,以下列表可能對初學者獲得良好的資料庫效能有所幫助:

  • 使用本教程中 RDBMS 概念章節中解釋的 3BNF 資料庫設計。

  • 避免數字到字元的轉換,因為數字和字元的比較方式不同,會導致效能下降。

  • 在使用 SELECT 語句時,僅獲取所需的資訊,並避免在 SELECT 查詢中使用 *,因為它會不必要地載入系統。

  • 在所有頻繁進行搜尋操作的表上小心地建立索引。避免在搜尋操作較少且插入和更新操作較多的表上建立索引。

  • 當 WHERE 子句中的列沒有關聯的索引時,會發生全表掃描。您可以透過在用作 WHERE 子句中 SQL 語句條件的列上建立索引來避免全表掃描。

  • 對實數和日期/時間值使用相等運算子要非常小心。這兩者都可能存在肉眼無法察覺的小差異,但這些差異會導致精確匹配變得不可能,從而阻止您的查詢返回任何行。

  • 謹慎使用模式匹配。LIKE COL% 是一個有效的 WHERE 條件,將返回集縮小到僅以字串 COL 開頭的那些記錄。但是,COL%Y 不會進一步縮小返回的結果集,因為 %Y 無法有效評估。進行評估的努力太大,無法考慮。在這種情況下,將使用 COL%,但 %Y 將被丟棄。出於同樣的原因,前導萬用字元 %COL 會有效地阻止整個過濾器被使用。

  • 微調您的 SQL 查詢,檢查查詢(和子查詢)的結構,SQL 語法,以發現您是否已設計表以支援快速資料操作並以最佳方式編寫了查詢,從而允許您的 DBMS 高效地操作資料。

  • 對於定期執行的查詢,嘗試使用過程。過程是一組可能很大的 SQL 語句。過程由資料庫引擎編譯,然後執行。與 SQL 語句不同,資料庫引擎無需在執行過程之前對其進行最佳化。

  • 如果可能,避免在查詢中使用邏輯運算子 OR。OR 不可避免地會減慢針對大尺寸表的幾乎任何查詢的速度。

  • 您可以透過刪除索引來最佳化批次資料載入。想象一下具有數千行的歷史表。該歷史表也可能有一個或多個索引。當您想到索引時,通常會想到更快的表訪問,但在批次載入的情況下,您可以透過刪除索引來獲益。

  • 在執行批處理事務時,在建立一定數量的記錄後執行 COMMIT,而不是在建立每條記錄後執行。

  • 計劃定期對資料庫進行碎片整理,即使這樣做意味著開發每週例程。

內建調優工具

Oracle 有許多用於管理 SQL 語句效能的工具,但其中兩個非常流行。這兩個工具是:

  • Explain plan - 該工具識別執行 SQL 語句時將採用的訪問路徑。

  • tkprof - 透過 SQL 語句處理每個階段經過的時間來衡量效能。

如果您只想在 Oracle 中測量查詢的經過時間,可以使用 SQL*Plus 命令 SET TIMING ON。

有關上述工具和資料庫碎片整理的更多詳細資訊,請檢視您的 RDBMS 文件。

廣告