12. SQL UNION 和 UNION ALL 操作符
UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。
請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同。
UNION 語法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
註釋:默認地,UNION 操作符選取不同的值。如果允許重複的值,請使用 UNION ALL。
UNION ALL 語法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
另外,UNION 結果集中的列名總是等於 UNION 中第一個 SELECT 語句中的列名。
下面的例子中使用的原始表:
Employees_China:
E_ID |
E_Name |
01 |
Zhang, Hua |
02 |
Wang, Wei |
03 |
Carter, Thomas |
04 |
Yang, Ming |
Employees_USA:
E_ID |
E_Name |
01 |
Adams, John |
02 |
Bush, George |
03 |
Carter, Thomas |
04 |
Gates, Bill |
UNION 實例
列出所有在中國和美國的不同的僱員名:
SELECT E_Name FROM Employees_China
UNION
SELECT E_Name FROM Employees_USA
結果
E_Name |
Zhang, Hua |
Wang, Wei |
Carter, Thomas |
Yang, Ming |
Adams, John |
Bush, George |
Gates, Bill |
註釋:這個命令無法列出在中國和美國的所有僱員。在上面的例子中,我們有兩個名字相同的僱員,他們當中只有一個人被列出來了。UNION 命令只會選取不同的值。
UNION ALL 命令和 UNION 命令幾乎是等效的,不過 UNION ALL 命令會列出所有的值。
SQL Statement 1
UNION ALL
SQL Statement 2
UNION ALL 實例
列出在中國和美國的所有的僱員:
SELECT E_Name FROM Employees_China
UNION ALL
SELECT E_Name FROM Employees_USA
結果
E_Name |
Zhang, Hua |
Wang, Wei |
Carter, Thomas |
Yang, Ming |
Adams, John |
Bush, George |
Carter, Thomas |
Gates, Bill |
13. SQL SELECT INTO 語句
SELECT INTO 語句從一個表中選取數據,然後把數據插入另一個表中。
SELECT INTO 語句常用於創建表的備份復件或者用於對記錄進行存檔。
SELECT INTO 語法
您可以把所有的列插入新表:
SELECT *
INTO new_table_name [IN externaldatabase]
FROM old_tablename
或者只把希望的列插入新表:
SELECT column_name(s)
INTO new_table_name [IN externaldatabase]
FROM old_tablename
SELECT INTO 實例 - 製作備份復件
下面的例子會製作 "Persons" 表的備份復件:
SELECT
*
INTO
Persons_backup
FROM Persons
IN 子句可用於向另一個數據庫中拷貝表:
SELECT
*
INTO
PersonsIN
'Backup.mdb'
FROM Persons
如果我們希望拷貝某些域,可以在 SELECT 語句後列出這些域:
SELECT
LastName,FirstName
INTO
Persons_backup
FROM Persons
SELECT INTO 實例 - 帶有 WHERE 子句
我們也可以添加 WHERE 子句。
下面的例子通過從 "Persons" 表中提取居住在 "Beijing" 的人的信息,創建了一個帶有兩個列的名爲"Persons_backup" 的表:
SELECT
LastName,Firstname
INTO
Persons_backup
FROM Persons
WHERE
City='Beijing'
SELECT INTO 實例 - 被連接的表
從一個以上的表中選取數據也是可以做到的。
下面的例子會創建一個名爲 "Persons_Order_Backup" 的新表,其中包含了從 Persons 和 Orders 兩個表中取得的信息:
SELECT
Persons.LastName,Orders.OrderNo
INTO
Persons_Order_Backup
FROM
Persons
INNER JOIN
Orders
ON
Persons.Id_P=Orders.Id_P
14. SQL CREATE DATABASE 語句
CREATE DATABASE 用於創建數據庫。
CREATE DATABASE 語法
CREATE DATABASE database_name
CREATE DATABASE 實例
現在我們希望創建一個名爲 "my_db" 的數據庫。我們使用下面的 CREATE DATABASE 語句:
CREATE DATABASE my_db
可以通過 CREATE TABLE 來添加數據庫表。
15. SQL CREATE TABLE 語句
CREATE TABLE 語句用於創建數據庫中的表。
CREATE TABLE 語法
CREATE TABLE 表名稱
(
列名稱1 數據類型,
列名稱2 數據類型,
列名稱3 數據類型,
....
)
數據類型(data_type)規定了列可容納何種數據類型。下面的表格包含了SQL中最常用的數據類型:
數據類型 |
描述 |
· integer(size) · int(size) · smallint(size) · tinyint(size) |
僅容納整數。在括號內規定數字的最大位數。 |
· decimal(size,d) · numeric(size,d) |
容納帶有小數的數字。 "size" 規定數字的最大位數。"d" 規定小數點右側的最大位數。 |
char(size) |
容納固定長度的字符串(可容納字母、數字以及特殊字符)。 在括號中規定字符串的長度。 |
varchar(size) |
容納可變長度的字符串(可容納字母、數字以及特殊的字符)。 在括號中規定字符串的最大長度。 |
date(yyyymmdd) |
容納日期。 |
CREATE TABLE 實例
本例演示如何創建名爲 "Person" 的表。
該表包含 5 個列,列名分別是:"Id_P"、"LastName"、"FirstName"、"Address" 以及 "City":
CREATE TABLE Persons
(
Id_P int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
Id_P 列的數據類型是 int,包含整數。其餘 4 列的數據類型是 varchar,最大長度爲 255 個字符。
空的"Persons" 表類似這樣:
Id_P |
LastName |
FirstName |
Address |
City |
|
|
|
|
|
可使用 INSERTINTO 語句向空表寫入數據。
16. SQL 約束 (Constraints)
約束用於限制加入表的數據的類型。
可以在創建表時規定約束(通過 CREATE TABLE 語句),或者在表創建之後也可以(通過 ALTER TABLE 語句)。
我們將主要探討以下幾種約束:
· NOT NULL
· UNIQUE
· PRIMARY KEY
· FOREIGN KEY
· CHECK
· DEFAULT
註釋:在下面的章節,我們會詳細講解每一種約束。
17. SQL NOT NULL 約束
NOT NULL 約束強制列不接受 NULL 值。
NOT NULL 約束強制字段始終包含值。這意味着,如果不向字段添加值,就無法插入新記錄或者更新記錄。
下面的 SQL 語句強制 "Id_P" 列和 "LastName" 列不接受 NULL 值:
CREATE TABLE Persons
(
Id_P int NOT NULL
,
LastName varchar(255) NOT NULL
,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
18. SQL UNIQUE 約束
UNIQUE 約束唯一標識數據庫表中的每條記錄。
UNIQUE 和 PRIMARY KEY 約束均爲列或列集合提供了唯一性的保證。
PRIMARY KEY 擁有自動定義的 UNIQUE 約束。
請注意,每個表可以有多個 UNIQUE 約束,但是每個表只能有一個 PRIMARY KEY 約束。
UNIQUE Constraint on CREATE TABLE
下面的 SQL 在"Persons" 表創建時在 "Id_P" 列創建 UNIQUE 約束:
MySQL:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (Id_P)
)
SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
Id_P int NOT NULL UNIQUE
,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
如果需要命名 UNIQUE 約束,以及爲多個列定義 UNIQUE 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
)
UNIQUE Constraint on ALTER TABLE
當表已被創建時,如需在 "Id_P" 列創建 UNIQUE 約束,請使用下列 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD UNIQUE (Id_P)
如需命名 UNIQUE 約束,並定義多個列的 UNIQUE 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
撤銷 UNIQUE 約束
如需撤銷 UNIQUE 約束,請使用下面的 SQL:
MySQL:
ALTER TABLE Persons
DROP INDEX uc_PersonID
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT uc_PersonID
19. SQL PRIMARY KEY 約束
PRIMARY KEY 約束唯一標識數據庫表中的每條記錄。主鍵必須包含唯一的值。主鍵列不能包含 NULL 值。
每個表都應該有一個主鍵,並且每個表只能有一個主鍵。
PRIMARY KEY Constraint on CREATE TABLE
下面的 SQL 在"Persons" 表創建時在 "Id_P" 列創建 PRIMARY KEY 約束:
MySQL:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (Id_P)
)
SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
Id_P int NOT NULL PRIMARY KEY
,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
如果需要命名 PRIMARY KEY 約束,以及爲多個列定義 PRIMARY KEY 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (Id_P,LastName)
)
PRIMARY KEY Constraint on ALTER TABLE
如果在表已存在的情況下爲 "Id_P" 列創建 PRIMARY KEY 約束,請使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD PRIMARY KEY (Id_P)
如果需要命名 PRIMARY KEY 約束,以及爲多個列定義 PRIMARY KEY 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (Id_P,LastName)
註釋:如果您使用 ALTER TABLE 語句添加主鍵,必須把主鍵列聲明爲不包含 NULL 值(在表首次創建時)。
撤銷 PRIMARY KEY 約束
如需撤銷 PRIMARY KEY 約束,請使用下面的 SQL:
MySQL:
ALTER TABLE Persons
DROP PRIMARY KEY
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT pk_PersonID
20. SQL FOREIGN KEY 約束
一個表中的 FOREIGN KEY 指向另一個表中的 PRIMARY KEY。
讓我們通過一個例子來解釋外鍵。請看下面兩個表:
"Persons" 表:
Id_P |
LastName |
FirstName |
Address |
City |
1 |
Adams |
John |
Oxford Street |
London |
2 |
Bush |
George |
Fifth Avenue |
New York |
3 |
Carter |
Thomas |
Changan Street |
Beijing |
"Orders" 表:
Id_O |
OrderNo |
Id_P |
1 |
77895 |
3 |
2 |
44678 |
3 |
3 |
22456 |
1 |
4 |
24562 |
1 |
請注意,"Orders" 中的 "Id_P" 列指向 "Persons" 表中的 "Id_P" 列。
"Persons" 表中的 "Id_P" 列是 "Persons" 表中的 PRIMARY KEY。
"Orders" 表中的 "Id_P" 列是 "Orders" 表中的 FOREIGN KEY。
FOREIGN KEY 約束用於預防破壞表之間連接的動作。
FOREIGN KEY 約束也能防止非法數據插入外鍵列,因爲它必須是它指向的那個表中的值之一。
FOREIGN KEY Constraint on CREATE TABLE
下面的 SQL 在"Orders" 表創建時爲 "Id_P" 列創建 FOREIGN KEY:
MySQL:
CREATE TABLE Orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
PRIMARY KEY (Id_O),
FOREIGN KEY (Id_P) REFERENCES Persons(Id_P)
)
SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
Id_O int NOT NULL PRIMARY KEY,
OrderNo int NOT NULL,
Id_P int FOREIGN KEY REFERENCES Persons(Id_P)
)
如果需要命名 FOREIGN KEY 約束,以及爲多個列定義 FOREIGN KEY 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
PRIMARY KEY (Id_O),
CONSTRAINT fk_PerOrders FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)
)
FOREIGN KEY Constraint on ALTER TABLE
如果在"Orders" 表已存在的情況下爲 "Id_P" 列創建 FOREIGN KEY 約束,請使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)
如果需要命名 FOREIGN KEY 約束,以及爲多個列定義 FOREIGN KEY 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD CONSTRAINT fk_PerOrders
FOREIGN KEY (Id_P)
REFERENCES Persons(Id_P)
撤銷 FOREIGN KEY 約束
如需撤銷 FOREIGN KEY 約束,請使用下面的 SQL:
MySQL:
ALTER TABLE Orders
DROP FOREIGN KEY fk_PerOrders
SQL Server / Oracle / MS Access:
ALTER TABLE Orders
DROP CONSTRAINT fk_PerOrders
21. SQL CHECK 約束
CHECK 約束用於限制列中的值的範圍。
如果對單個列定義 CHECK 約束,那麼該列只允許特定的值。
如果對一個表定義 CHECK 約束,那麼此約束會在特定的列中對值進行限制。
CHECK Constraint on CREATE TABLE
下面的 SQL 在"Persons" 表創建時爲 "Id_P" 列創建 CHECK 約束。CHECK 約束規定 "Id_P" 列必須只包含大於 0 的整數。
My SQL:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CHECK (Id_P>0)
)
SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
Id_P int NOT NULL CHECK (Id_P>0)
,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
如果需要命名 CHECK 約束,以及爲多個列定義 CHECK 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')
)
CHECK Constraint on ALTER TABLE
如果在表已存在的情況下爲 "Id_P" 列創建 CHECK 約束,請使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CHECK (Id_P>0)
如果需要命名 CHECK 約束,以及爲多個列定義 CHECK 約束,請使用下面的 SQL 語法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')
撤銷 CHECK 約束
如需撤銷 CHECK 約束,請使用下面的 SQL:
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT chk_Person
MySQL:
ALTER TABLE Persons
DROP CHECK chk_Person
22. SQL DEFAULT 約束
DEFAULT 約束用於向列中插入默認值。
如果沒有規定其他的值,那麼會將默認值添加到所有的新記錄。
DEFAULT Constraint on CREATE TABLE
下面的 SQL 在"Persons" 表創建時爲 "City" 列創建 DEFAULT 約束:
My SQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'Sandnes'
)
通過使用類似 GETDATE() 這樣的函數,DEFAULT 約束也可以用於插入系統值:
CREATE TABLE Orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
OrderDate date DEFAULT GETDATE()
)
DEFAULT Constraint on ALTER TABLE
如果在表已存在的情況下爲 "City" 列創建 DEFAULT 約束,請使用下面的 SQL:
MySQL:
ALTER TABLE Persons
ALTER City SET DEFAULT 'SANDNES'
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ALTER COLUMN City SET DEFAULT 'SANDNES'
撤銷 DEFAULT 約束
如需撤銷 DEFAULT 約束,請使用下面的 SQL:
MySQL:
ALTER TABLE Persons
ALTER City DROP DEFAULT
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ALTER COLUMN City DROP DEFAULT
23. SQL CREATE INDEX 語句
用於在表中創建索引。在不讀取整個表的情況下,索引使數據庫應用程序可以更快地查找數據。
您可以在表中創建索引,以便更加快速高效地查詢數據。用戶無法看到索引,它們只能被用來加速搜索/查詢。
註釋:更新一個包含索引的表需要比更新一個沒有索引的表更多的時間,這是由於索引本身也需要更新。因此,理想的做法是僅僅在常常被搜索的列(以及表)上面創建索引。
CREATE INDEX 語法
在表上創建一個簡單的索引。允許使用重複的值:
CREATE INDEX index_name
ON table_name (column_name)
註釋:"column_name"規定需要索引的列。
CREATE UNIQUE INDEX 語法
在表上創建一個唯一的索引。唯一的索引意味着兩個行不能擁有相同的索引值。
CREATE UNIQUE INDEX index_name
ON table_name (column_name)
CREATE INDEX 實例
本例會創建一個簡單的索引,名爲 "PersonIndex",在 Person 表的 LastName 列:
CREATE INDEX PersonIndex
ON Person (LastName)
如果您希望以降序索引某個列中的值,您可以在列名稱之後添加保留字 DESC:
CREATE INDEX PersonIndex
ON Person (LastName DESC)
假如您希望索引不止一個列,您可以在括號中列出這些列的名稱,用逗號隔開:
CREATE INDEX PersonIndex
ON Person (LastName, FirstName)
24. SQL 撤銷索引、表以及數據庫
DROP INDEX 語句
我們可以使用 DROP INDEX 命令刪除表格中的索引。
用於 MicrosoftSQLJet (以及 Microsoft Access) 的語法:
DROP INDEX index_name ON table_name
用於 MS SQLServer 的語法:
DROP INDEX table_name.index_name
用於 IBM DB2 和 Oracle 語法:
DROP INDEX index_name
用於 MySQL 的語法:
ALTER TABLE table_name DROP INDEX index_name
DROP TABLE 語句
DROP TABLE 語句用於刪除表(表的結構、屬性以及索引也會被刪除):
DROP TABLE 表名稱
DROP DATABASE 語句
DROP DATABASE 語句用於刪除數據庫:
DROP DATABASE 數據庫名稱
TRUNCATE TABLE 語句
如果我們僅僅需要除去表內的數據,但並不刪除表本身,那麼我們該如何做呢?
請使用 TRUNCATETABLE 命令(僅僅刪除表格中的數據):
TRUNCATE TABLE 表名稱
25. SQL ALTER TABLE 語句
ALTER TABLE 語句用於在已有的表中添加、修改或刪除列。
ALTER TABLE 語法
如需在表中添加列,請使用下列語法:
ALTER TABLE table_name
ADD column_name datatype
要刪除表中的列,請使用下列語法:
ALTER TABLE table_name
DROP COLUMN column_name
註釋:某些數據庫系統不允許這種在數據庫表中刪除列的方式 (DROP COLUMN column_name)。
要改變表中列的數據類型,請使用下列語法:
ALTER TABLE table_name
ALTER COLUMN column_name datatype
原始的表 (用在例子中的):
Persons 表:
Id |
LastName |
FirstName |
Address |
City |
1 |
Adams |
John |
Oxford Street |
London |
2 |
Bush |
George |
Fifth Avenue |
New York |
3 |
Carter |
Thomas |
Changan Street |
Beijing |
ALTER TABLE 實例
現在,我們希望在表 "Persons" 中添加一個名爲 "Birthday" 的新列。
我們使用下列 SQL 語句:
ALTER TABLE Persons
ADD Birthday date
請注意,新列 "Birthday" 的類型是 date,可以存放日期。數據類型規定列中可以存放的數據的類型。
新的"Persons" 表類似這樣:
Id |
LastName |
FirstName |
Address |
City |
Birthday |
1 |
Adams |
John |
Oxford Street |
London |
|
2 |
Bush |
George |
Fifth Avenue |
New York |
|
3 |
Carter |
Thomas |
Changan Street |
Beijing |
|
改變數據類型實例
現在我們希望改變 "Persons" 表中 "Birthday" 列的數據類型。
我們使用下列 SQL 語句:
ALTER TABLE Persons
ALTER COLUMN Birthday year
請注意,"Birthday" 列的數據類型是 year,可以存放 2 位或 4 位格式的年份。
DROP COLUMN 實例
接下來,我們刪除 "Person" 表中的 "Birthday" 列:
ALTER TABLE Person
DROP COLUMN Birthday
Persons 表會成爲這樣:
Id |
LastName |
FirstName |
Address |
City |
1 |
Adams |
John |
Oxford Street |
London |
2 |
Bush |
George |
Fifth Avenue |
New York |
3 |
Carter |
Thomas |
Changan Street |
Beijing |
26. SQL AUTO INCREMENT 字段
Auto-increment 會在新記錄插入表中時生成一個唯一的數字。
我們通常希望在每次插入新記錄時,自動地創建主鍵字段的值。我們可以在表中創建一個 auto-increment 字段。
用於 MySQL 的語法
下列 SQL 語句把"Persons" 表中的 "P_Id" 列定義爲 auto-increment 主鍵:
CREATE TABLE Persons
(
P_Id int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (P_Id)
)
MySQL 使用 AUTO_INCREMENT 關鍵字來執行 auto-increment 任務。
默認地,AUTO_INCREMENT 的開始值是 1,每條新記錄遞增 1。
要讓AUTO_INCREMENT 序列以其他的值起始,請使用下列 SQL 語法:
ALTER TABLE Persons AUTO_INCREMENT=100
要在"Persons" 表中插入新記錄,我們不必爲 "P_Id" 列規定值(會自動添加一個唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Bill','Gates')
上面的 SQL 語句會在 "Persons" 表中插入一條新記錄。"P_Id" 會被賦予一個唯一的值。"FirstName" 會被設置爲 "Bill","LastName" 列會被設置爲 "Gates"。
用於 SQL Server 的語法
下列 SQL 語句把"Persons" 表中的 "P_Id" 列定義爲 auto-increment 主鍵:
CREATE TABLE Persons
(
P_Id int PRIMARY KEY IDENTITY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
MS SQL 使用 IDENTITY 關鍵字來執行 auto-increment 任務。
默認地,IDENTITY 的開始值是 1,每條新記錄遞增 1。
要規定"P_Id" 列以 20 起始且遞增 10,請把 identity 改爲 IDENTITY(20,10)
要在"Persons" 表中插入新記錄,我們不必爲 "P_Id" 列規定值(會自動添加一個唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Bill','Gates')
上面的 SQL 語句會在 "Persons" 表中插入一條新記錄。"P_Id" 會被賦予一個唯一的值。"FirstName" 會被設置爲 "Bill","LastName" 列會被設置爲 "Gates"。
用於 Access 的語法
下列 SQL 語句把"Persons" 表中的 "P_Id" 列定義爲 auto-increment 主鍵:
CREATE TABLE Persons
(
P_Id int PRIMARY KEY AUTOINCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
MS Access 使用 AUTOINCREMENT 關鍵字來執行 auto-increment 任務。
默認地,AUTOINCREMENT 的開始值是 1,每條新記錄遞增 1。
要規定"P_Id" 列以 20 起始且遞增 10,請把 autoincrement 改爲 AUTOINCREMENT(20,10)
要在"Persons" 表中插入新記錄,我們不必爲 "P_Id" 列規定值(會自動添加一個唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Bill','Gates')
上面的 SQL 語句會在 "Persons" 表中插入一條新記錄。"P_Id" 會被賦予一個唯一的值。"FirstName" 會被設置爲 "Bill","LastName" 列會被設置爲 "Gates"。
用於 Oracle 的語法
在 Oracle 中,代碼稍微複雜一點。
您必須通過 sequence 對創建 auto-increment 字段(該對象生成數字序列)。
請使用下面的 CREATE SEQUENCE 語法:
CREATE SEQUENCE seq_person
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10
上面的代碼創建名爲 seq_person 的序列對象,它以 1 起始且以 1 遞增。該對象緩存 10 個值以提高性能。CACHE 選項規定了爲了提高訪問速度要存儲多少個序列值。
要在"Persons" 表中插入新記錄,我們必須使用 nextval 函數(該函數從 seq_person 序列中取回下一個值):
INSERT INTO Persons (P_Id,FirstName,LastName)
VALUES (seq_person.nextval,'Lars','Monsen')
上面的 SQL 語句會在 "Persons" 表中插入一條新記錄。"P_Id" 的賦值是來自 seq_person 序列的下一個數字。"FirstName" 會被設置爲 "Bill","LastName" 列會被設置爲 "Gates"。
27. SQL VIEW(視圖)
在 SQL 中,視圖是基於 SQL 語句的結果集的可視化的表。
視圖包含行和列,就像一個真實的表。視圖中的字段就是來自一個或多個數據庫中的真實的表中的字段。我們可以向視圖添加 SQL 函數、WHERE 以及 JOIN 語句,我們也可以提交數據,就像這些來自於某個單一的表。
註釋:數據庫的設計和結構不會受到視圖中的函數、where 或 join 語句的影響。
CREATE VIEW 語法
CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
註釋:視圖總是顯示最近的數據。每當用戶查詢視圖時,數據庫引擎通過使用 SQL 語句來重建數據。
CREATE VIEW 實例
可以從某個查詢內部、某個存儲過程內部,或者從另一個視圖內部來使用視圖。通過向視圖添加函數、join 等等,我們可以向用戶精確地提交我們希望提交的數據。
樣本數據庫 Northwind 擁有一些被默認安裝的視圖。視圖 "Current Product List" 會從 Products 表列出所有正在使用的產品。這個視圖使用下列 SQL 創建:
CREATE VIEW
[Current Product List]AS
SELECT
ProductID,ProductName
FROM
Products
WHERE
Discontinued=No
我們可以查詢上面這個視圖:
SELECT * FROM [Current Product List]
Northwind 樣本數據庫的另一個視圖會選取 Products 表中所有單位價格高於平均單位價格的產品:
CREATE VIEW
[Products Above Average Price]AS
SELECT
ProductName,UnitPrice
FROM
Products
WHERE
UnitPrice>(SELECT AVG(UnitPrice) FROM Products)
我們可以像這樣查詢上面這個視圖:
SELECT * FROM [Products Above Average Price]
另一個來自 Northwind 數據庫的視圖實例會計算在 1997 年每個種類的銷售總數。請注意,這個視圖會從另一個名爲 "ProductSales for 1997" 的視圖那裏選取數據:
CREATE VIEW
[Category Sales For 1997]AS
SELECT DISTINCT
CategoryName,Sum(ProductSales)AS
CategorySales
FROM
[Product Sales for 1997]
GROUP BY
CategoryName
我們可以像這樣查詢上面這個視圖:
SELECT * FROM [Category Sales For 1997]
我們也可以向查詢添加條件。現在,我們僅僅需要查看 "Beverages" 類的全部銷量:
SELECT
*FROM
[Category Sales For 1997]
WHERE
CategoryName='Beverages'
SQL 更新視圖
您可以使用下面的語法來更新視圖:
SQL CREATE OR REPLACE VIEW Syntax
CREATE OR REPLACE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
現在,我們希望向 "Current Product List" 視圖添加 "Category" 列。我們將通過下列 SQL 更新視圖:
CREATE VIEW [Current Product List] AS
SELECT ProductID,ProductName,Category
FROM Products
WHERE Discontinued=No
SQL 撤銷視圖
您可以通過 DROP VIEW 命令來刪除視圖。
SQL DROP VIEW Syntax
DROP VIEW view_name
28. SQL Date 函數
當我們處理日期時,最難的任務恐怕是確保所插入的日期的格式,與數據庫中日期列的格式相匹配。
只要數據包含的只是日期部分,運行查詢就不會出問題。但是,如果涉及時間,情況就有點複雜了。
在討論日期查詢的複雜性之前,我們先來看看最重要的內建日期處理函數。
MySQL Date 函數
下面的表格列出了 MySQL 中最重要的內建日期函數:
函數 |
描述 |
返回當前的日期和時間 |
|
返回當前的日期 |
|
返回當前的時間 |
|
提取日期或日期/時間表達式的日期部分 |
|
返回日期/時間按的單獨部分 |
|
給日期添加指定的時間間隔 |
|
從日期減去指定的時間間隔 |
|
返回兩個日期之間的天數 |
|
用不同的格式顯示日期/時間 |
SQL Server Date 函數
下面的表格列出了 SQL Server 中最重要的內建日期函數:
函數 |
描述 |
返回當前日期和時間 |
|
返回日期/時間的單獨部分 |
|
在日期中添加或減去指定的時間間隔 |
|
返回兩個日期之間的時間 |
|
用不同的格式顯示日期/時間 |
SQL Date 數據類型
MySQL 使用下列數據類型在數據庫中存儲日期或日期/時間值:
· DATE - 格式 YYYY-MM-DD
· DATETIME - 格式: YYYY-MM-DD HH:MM:SS
· TIMESTAMP - 格式: YYYY-MM-DD HH:MM:SS
· YEAR - 格式 YYYY 或 YY
SQL Server 使用下列數據類型在數據庫中存儲日期或日期/時間值:
· DATE - 格式 YYYY-MM-DD
· DATETIME - 格式: YYYY-MM-DD HH:MM:SS
· SMALLDATETIME - 格式: YYYY-MM-DD HH:MM:SS
· TIMESTAMP - 格式: 唯一的數字
SQL 日期處理
如果不涉及時間部分,那麼我們可以輕鬆地比較兩個日期!
假設我們有下面這個 "Orders" 表:
OrderId |
ProductName |
OrderDate |
1 |
computer |
2008-12-26 |
2 |
printer |
2008-12-26 |
3 |
electrograph |
2008-11-12 |
4 |
telephone |
2008-10-19 |
現在,我們希望從上表中選取 OrderDate 爲 "2008-12-26" 的記錄。
我們使用如下 SELECT 語句:
SELECT * FROM Orders WHERE OrderDate='2008-12-26'
結果集:
OrderId |
ProductName |
OrderDate |
1 |
computer |
2008-12-26 |
3 |
electrograph |
2008-12-26 |
現在假設 "Orders" 類似這樣(請注意 "OrderDate" 列中的時間部分):
OrderId |
ProductName |
OrderDate |
1 |
computer |
2008-12-26 16:23:55 |
2 |
printer |
2008-12-26 10:45:26 |
3 |
electrograph |
2008-11-12 14:12:08 |
4 |
telephone |
2008-10-19 12:56:10 |
如果我們使用上面的 SELECT 語句:
SELECT * FROM Orders WHERE OrderDate='2008-12-26'
那麼我們得不到結果。這是由於該查詢不含有時間部分的日期。
提示:如果您希望使查詢簡單且更易維護,那麼請不要在日期中使用時間部分!
29. SQL NULL 值
SQL NULL值
如果表中的某個列是可選的,那麼我們可以在不向該列添加值的情況下插入新記錄或更新已有的記錄。這意味着該字段將以 NULL 值保存。NULL 值的處理方式與其他值不同。NULL 用作未知的或不適用的值的佔位符。
註釋:無法比較 NULL 和 0;它們是不等價的。
請看下面的 "Persons" 表:
Id |
LastName |
FirstName |
Address |
City |
1 |
Adams |
John |
|
London |
2 |
Bush |
George |
Fifth Avenue |
New York |
3 |
Carter |
Thomas |
|
Beijing |
假如"Persons" 表中的 "Address" 列是可選的。這意味着如果在 "Address" 列插入一條不帶值的記錄,"Address" 列會使用 NULL 值保存。
那麼我們如何測試 NULL 值呢?
無法使用比較運算符來測試 NULL 值,比如 =, <, 或者 <>。我們必須使用 IS NULL 和 IS NOT NULL 操作符。
SQL IS NULL
我們如何僅僅選取在 "Address" 列中帶有 NULL 值的記錄呢?
我們必須使用 IS NULL 操作符:
SELECT LastName,FirstName,Address FROM Persons
WHERE Address IS NULL
結果集:
LastName |
FirstName |
Address |
Adams |
John |
|
Carter |
Thomas |
|
提示:請始終使用 IS NULL 來查找 NULL 值。
SQL IS NOT NULL
我們如何選取在 "Address" 列中不帶有 NULL 值的記錄呢?
我們必須使用 IS NOT NULL 操作符:
SELECT LastName,FirstName,Address FROM Persons
WHERE Address IS NOT NULL
結果集:
LastName |
FirstName |
Address |
Bush |
George |
Fifth Avenue |
在下一節中,我們瞭解 ISNULL()、NVL()、IFNULL() 和 COALESCE() 函數。
30. SQL NULL 函數
SQL ISNULL()、NVL()、IFNULL() 和 COALESCE() 函數
請看下面的 "Products" 表:
P_Id |
ProductName |
UnitPrice |
UnitsInStock |
UnitsOnOrder |
1 |
computer |
699 |
25 |
15 |
2 |
printer |
365 |
36 |
|
3 |
telephone |
280 |
159 |
57 |
假如"UnitsOnOrder" 是可選的,而且可以包含 NULL 值。我們使用如下 SELECT 語句:
SELECT ProductName,UnitPrice*(UnitsInStock+UnitsOnOrder)
FROM Products
在上面的例子中,如果有 "UnitsOnOrder" 值是 NULL,那麼結果是 NULL。
微軟的 ISNULL() 函數用於規定如何處理 NULL 值。
NVL(), IFNULL() 和 COALESCE() 函數也可以達到相同的結果。在這裏,我們希望 NULL 值爲 0。
下面,如果 "UnitsOnOrder" 是 NULL,則不利於計算,因此如果值是 NULL 則 ISNULL() 返回 0。
SQL Server / MS Access
SELECT ProductName,UnitPrice*(UnitsInStock+ISNULL(UnitsOnOrder,0))
FROM Products
Oracle
Oracle 沒有 ISNULL() 函數。不過,我們可以使用 NVL() 函數達到相同的結果:
SELECT ProductName,UnitPrice*(UnitsInStock+NVL(UnitsOnOrder,0))
FROM Products
MySQL
MySQL 也擁有類似 ISNULL() 的函數。不過它的工作方式與微軟的 ISNULL() 函數有點不同。
在 MySQL 中,我們可以使用 IFNULL() 函數,就像這樣:
SELECT ProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0))
FROM Products
或者我們可以使用 COALESCE() 函數,就像這樣:
SELECT ProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0))
FROM Products
31. SQL 數據類型
Microsoft Access 數據類型
數據類型 |
描述 |
存儲 |
Text |
用於文本或文本與數字的組合。最多 255 個字符。 |
|
Memo |
Memo 用於更大數量的文本。最多存儲 65,536 個字符。 註釋:無法對 memo 字段進行排序。不過它們是可搜索的。 |
|
Byte |
允許 0 到 255 的數字。 |
1 字節 |
Integer |
允許介於 -32,768 到 32,767 之間的數字。 |
2 字節 |
Long |
允許介於 -2,147,483,648 與 2,147,483,647 之間的全部數字 |
4 字節 |
Single |
單精度浮點。處理大多數小數。 |
4 字節 |
Double |
雙精度浮點。處理大多數小數。 |
8 字節 |
Currency |
用於貨幣。支持 15 位的元,外加 4 位小數。 提示:您可以選擇使用哪個國家的貨幣。 |
8 字節 |
AutoNumber |
AutoNumber 字段自動爲每條記錄分配數字,通常從 1 開始。 |
4 字節 |
Date/Time |
用於日期和時間 |
8 字節 |
Yes/No |
邏輯字段,可以顯示爲 Yes/No、True/False 或 On/Off。 在代碼中,使用常量 True 和 False (等價於 1 和 0) 註釋:Yes/No 字段中不允許 Null 值 |
1 比特 |
Ole Object |
可以存儲圖片、音頻、視頻或其他 BLOBs (Binary Large OBjects) |
最多 1GB |
Hyperlink |
包含指向其他文件的鏈接,包括網頁。 |
|
Lookup Wizard |
允許你創建一個可從下列列表中進行選擇的選項列表。 |
4 字節 |
MySQL 數據類型
在 MySQL 中,有三種主要的類型:文本、數字和日期/時間類型。
Text 類型:
數據類型 |
描述 |
CHAR(size) |
保存固定長度的字符串(可包含字母、數字以及特殊字符)。在括號中指定字符串的長度。最多 255 個字符。 |
VARCHAR(size) |
保存可變長度的字符串(可包含字母、數字以及特殊字符)。在括號中指定字符串的最大長度。最多 255 個字符。 註釋:如果值的長度大於 255,則被轉換爲 TEXT 類型。 |
TINYTEXT |
存放最大長度爲 255 個字符的字符串。 |
TEXT |
存放最大長度爲 65,535 個字符的字符串。 |
BLOB |
用於 BLOBs (Binary Large OBjects)。存放最多 65,535 字節的數據。 |
MEDIUMTEXT |
存放最大長度爲 16,777,215 個字符的字符串。 |
MEDIUMBLOB |
用於 BLOBs (Binary Large OBjects)。存放最多 16,777,215 字節的數據。 |
LONGTEXT |
存放最大長度爲 4,294,967,295 個字符的字符串。 |
LONGBLOB |
用於 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字節的數據。 |
ENUM(x,y,z,etc.) |
允許你輸入可能值的列表。可以在 ENUM 列表中列出最大 65535 個值。如果列表中不存在插入的值,則插入空值。 註釋:這些值是按照你輸入的順序存儲的。 可以按照此格式輸入可能的值:ENUM('X','Y','Z') |
SET |
與 ENUM 類似,SET 最多隻能包含 64 個列表項,不過 SET 可存儲一個以上的值。 |
Number 類型:
數據類型 |
描述 |
TINYINT(size) |
-128 到 127 常規。0 到 255 無符號*。在括號中規定最大位數。 |
SMALLINT(size) |
-32768 到 32767 常規。0 到 65535 無符號*。在括號中規定最大位數。 |
MEDIUMINT(size) |
-8388608 到 8388607 普通。0 to 16777215 無符號*。在括號中規定最大位數。 |
INT(size) |
-2147483648 到 2147483647 常規。0 到 4294967295 無符號*。在括號中規定最大位數。 |
BIGINT(size) |
-9223372036854775808 到 9223372036854775807 常規。0 到 18446744073709551615 無符號*。在括號中規定最大位數。 |
FLOAT(size,d) |
帶有浮動小數點的小數字。在括號中規定最大位數。在 d 參數中規定小數點右側的最大位數。 |
DOUBLE(size,d) |
帶有浮動小數點的大數字。在括號中規定最大位數。在 d 參數中規定小數點右側的最大位數。 |
DECIMAL(size,d) |
作爲字符串存儲的 DOUBLE 類型,允許固定的小數點。 |
* 這些整數類型擁有額外的選項 UNSIGNED。通常,整數可以是負數或正數。如果添加 UNSIGNED 屬性,那麼範圍將從 0 開始,而不是某個負數。
Date 類型:
數據類型 |
描述 |
DATE() |
日期。格式:YYYY-MM-DD 註釋:支持的範圍是從 '1000-01-01' 到 '9999-12-31' |
DATETIME() |
*日期和時間的組合。格式:YYYY-MM-DD HH:MM:SS 註釋:支持的範圍是從 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' |
TIMESTAMP() |
*時間戳。TIMESTAMP 值使用 Unix 紀元('1970-01-01 00:00:00' UTC) 至今的描述來存儲。格式:YYYY-MM-DD HH:MM:SS 註釋:支持的範圍是從 '1970-01-01 00:00:01' UTC 到 '2038-01-09 03:14:07' UTC |
TIME() |
時間。格式:HH:MM:SS 註釋:支持的範圍是從 '-838:59:59' 到 '838:59:59' |
YEAR() |
2 位或 4 位格式的年。 註釋:4 位格式所允許的值:1901 到 2155。2 位格式所允許的值:70 到 69,表示從 1970 到 2069。 |
* 即便 DATETIME 和 TIMESTAMP 返回相同的格式,它們的工作方式很不同。在 INSERT 或 UPDATE 查詢中,TIMESTAMP 自動把自身設置爲當前的日期和時間。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。
SQL Server 數據類型
Character 字符串:
數據類型 |
描述 |
存儲 |
char(n) |
固定長度的字符串。最多 8,000 個字符。 |
n |
varchar(n) |
可變長度的字符串。最多 8,000 個字符。 |
|
varchar(max) |
可變長度的字符串。最多 1,073,741,824 個字符。 |
|
text |
可變長度的字符串。最多 2GB 字符數據。 |
|
Unicode 字符串:
數據類型 |
描述 |
存儲 |
nchar(n) |
固定長度的 Unicode 數據。最多 4,000 個字符。 |
|
nvarchar(n) |
可變長度的 Unicode 數據。最多 4,000 個字符。 |
|
nvarchar(max) |
可變長度的 Unicode 數據。最多 536,870,912 個字符。 |
|
ntext |
可變長度的 Unicode 數據。最多 2GB 字符數據。 |
|
Binary 類型:
數據類型 |
描述 |
存儲 |
bit |
允許 0、1 或 NULL |
|
binary(n) |
固定長度的二進制數據。最多 8,000 字節。 |
|
varbinary(n) |
可變長度的二進制數據。最多 8,000 字節。 |
|
varbinary(max) |
可變長度的二進制數據。最多 2GB 字節。 |
|
image |
可變長度的二進制數據。最多 2GB。 |
|
Number 類型:
數據類型 |
描述 |
存儲 |
tinyint |
允許從 0 到 255 的所有數字。 |
1 字節 |
smallint |
允許從 -32,768 到 32,767 的所有數字。 |
2 字節 |
int |
允許從 -2,147,483,648 到 2,147,483,647 的所有數字。 |
4 字節 |
bigint |
允許介於 -9,223,372,036,854,775,808 和 9,223,372,036,854,775,807 之間的所有數字。 |
8 字節 |
decimal(p,s) |
固定精度和比例的數字。允許從 -10^38 +1 到 10^38 -1 之間的數字。 p 參數指示可以存儲的最大位數(小數點左側和右側)。p 必須是 1 到 38 之間的值。默認是 18。 s 參數指示小數點右側存儲的最大位數。s 必須是 0 到 p 之間的值。默認是 0。 |
5-17 字節 |
numeric(p,s) |
固定精度和比例的數字。允許從 -10^38 +1 到 10^38 -1 之間的數字。 p 參數指示可以存儲的最大位數(小數點左側和右側)。p 必須是 1 到 38 之間的值。默認是 18。 s 參數指示小數點右側存儲的最大位數。s 必須是 0 到 p 之間的值。默認是 0。 |
5-17 字節 |
smallmoney |
介於 -214,748.3648 和 214,748.3647 之間的貨幣數據。 |
4 字節 |
money |
介於 -922,337,203,685,477.5808 和 922,337,203,685,477.5807 之間的貨幣數據。 |
8 字節 |
float(n) |
從 -1.79E + 308 到 1.79E + 308 的浮動精度數字數據。 參數 n 指示該字段保存 4 字節還是 8 字節。float(24) 保存 4 字節,而 float(53) 保存 8 字節。n 的默認值是 53。 |
4 或 8 字節 |
real |
從 -3.40E + 38 到 3.40E + 38 的浮動精度數字數據。 |
4 字節 |
Date 類型:
數據類型 |
描述 |
存儲 |
datetime |
從 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度爲 3.33 毫秒。 |
8 bytes |
datetime2 |
從 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度爲 100 納秒。 |
6-8 bytes |
smalldatetime |
從 1900 年 1 月 1 日 到 2079 年 6 月 6 日,精度爲 1 分鐘。 |
4 bytes |
date |
僅存儲日期。從 0001 年 1 月 1 日 到 9999 年 12 月 31 日。 |
3 bytes |
time |
僅存儲時間。精度爲 100 納秒。 |
3-5 bytes |
datetimeoffset |
與 datetime2 相同,外加時區偏移。 |
8-10 bytes |
timestamp |
存儲唯一的數字,每當創建或修改某行時,該數字會更新。timestamp 基於內部時鐘,不對應真實時間。每個表只能有一個 timestamp 變量。 |
|
其他數據類型:
數據類型 |
描述 |
sql_variant |
存儲最多 8,000 字節不同數據類型的數據,除了 text、ntext 以及 timestamp。 |
uniqueidentifier |
存儲全局標識符 (GUID)。 |
xml |
存儲 XML 格式化數據。最多 2GB。 |
cursor |
存儲對用於數據庫操作的指針的引用。 |
table |
存儲結果集,供稍後處理。 |
32. SQL 服務器 - RDBMS
現代的 SQL 服務器構建在 RDBMS 之上。
DBMS - 數據庫管理系統(Database ManagementSystem)
數據庫管理系統是一種可以訪問數據庫中數據的計算機程序。
DBMS 使我們有能力在數據庫中提取、修改或者存貯信息。
不同的 DBMS 提供不同的函數供查詢、提交以及修改數據。
RDBMS - 關係數據庫管理系統(RelationalDatabase Management System)
關係數據庫管理系統 (RDBMS) 也是一種數據庫管理系統,其數據庫是根據數據間的關係來組織和訪問數據的。
20 世紀 70 年代初,IBM 公司發明了 RDBMS。
RDBMS 是 SQL 的基礎,也是所有現代數據庫系統諸如 Oracle、SQL Server、IBM DB2、Sybase、MySQL 以及 Microsoft Access 的基礎。