在这里插入图片描述
不同的 SQL JOIN
在我们继续讲解实例之前,我们先列出您可以使用的不同的 SQL JOIN 类型:
INNER JOIN:如果表中有至少一个匹配,则返回行
LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行
FULL JOIN:只要其中一个表中存在匹配,则返回行
SELECT INTO 语句
SELECT INTO 语句可用于通过另一种模式创建一个新的空表。只需要添加促使查询没有数据返回的 WHERE 子句即可:
SELECT *
INTO newtable
FROM table1
WHERE 1=0;
SQL 通配符
在 SQL 中,通配符与 SQL LIKE 操作符一起使用。
SQL 通配符用于搜索表中的数据。
在 SQL 中,可使用以下通配符:
通配符 描述
% 替代 0 个或多个字符
_ 替代一个字符
[charlist] 字符列中的任何单一字符
[^charlist]
或
[!charlist] 不在字符列中的任何单一字符
使用 SQL [charlist] 通配符
MySQL 中使用 REGEXP 或 NOT REGEXP 运算符 (或 RLIKE 和 NOT RLIKE) 来操作正则表达式。
下面的 SQL 语句选取 name 以 “G”、“F” 或 “s” 开始的所有网站:
实例
SELECT * FROM Websites
WHERE name REGEXP '^[GFs]';
选取 name 以 A 到 H 字母开头的网站:
实例
SELECT * FROM Websites
WHERE name REGEXP '^[A-H]';
选取 name 不以 A 到 H 字母开头的网站:
实例
SELECT * FROM Websites
WHERE name REGEXP '^[^A-H]';
SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
INSERT INTO … SELECT
MySQL 数据库不支持 SELECT … INTO 语句,但支持 INSERT INTO … SELECT 。
当然你可以使用以下语句来拷贝表结构及数据:
CREATE TABLE 新表
AS
SELECT * FROM 旧表
SQL SELECT INTO 语法
我们可以复制所有的列插入到新表中:
SELECT *
INTO newtable [IN externaldb]
FROM table1;
或者只复制希望的列插入到新表中:
SELECT column_name(s)
INTO newtable [IN externaldb]
FROM table1;
lamp
提示:新表将会使用 SELECT 语句中定义的列名称和类型进行创建。您可以使用 AS 子句来应用新名称。
SQL SELECT INTO 实例
创建 Websites 的备份复件:
SELECT *
INTO WebsitesBackup2016
FROM Websites;
只复制一些列插入到新表中:
SELECT name, url
INTO WebsitesBackup2016
FROM Websites;
只复制中国的网站插入到新表中:
SELECT *
INTO WebsitesBackup2016
FROM Websites
WHERE country='CN';
复制多个表中的数据插入到新表中:
SELECT Websites.name, access_log.count, access_log.date
INTO WebsitesBackup2016
FROM Websites
LEFT JOIN access_log
ON Websites.id=access_log.site_id;
提示:SELECT INTO 语句可用于通过另一种模式创建一个新的空表。只需要添加促使查询没有数据返回的 WHERE 子句即可:
SELECT *
INTO newtable
FROM table1
WHERE 1=0;
SQL SELECT INTO 语法
我们可以复制所有的列插入到新表中:
SELECT *
INTO newtable [IN externaldb]
FROM table1;
或者只复制希望的列插入到新表中:
SELECT column_name(s)
INTO newtable [IN externaldb]
FROM table1;
SQL SELECT INTO 实例
创建 Websites 的备份复件:
SELECT *
INTO WebsitesBackup2016
FROM Websites;
只复制一些列插入到新表中:
SELECT name, url
INTO WebsitesBackup2016
FROM Websites;
只复制中国的网站插入到新表中:
SELECT *
INTO WebsitesBackup2016
FROM Websites
WHERE country='CN';
复制多个表中的数据插入到新表中:
SELECT Websites.name, access_log.count, access_log.date
INTO WebsitesBackup2016
FROM Websites
LEFT JOIN access_log
ON Websites.id=access_log.site_id;
提示:SELECT INTO 语句可用于通过另一种模式创建一个新的空表。只需要添加促使查询没有数据返回的 WHERE 子句即可:
SELECT *
INTO newtable
FROM table1
WHERE 1=0;
SQL INSERT INTO SELECT 语句
INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。
SQL INSERT INTO SELECT 语法
我们可以从一个表中复制所有的列插入到另一个已存在的表中:
INSERT INTO table2
SELECT * FROM table1;
或者我们可以只复制希望的列插入到另一个已存在的表中:
INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;
SQL INSERT INTO SELECT 实例
复制 “apps” 中的数据插入到 “Websites” 中:
实例
INSERT INTO Websites (name, country)
SELECT app_name, country FROM apps;
只复 id=1 的数据到 “Websites” 中:
实例
INSERT INTO Websites (name, country)
SELECT app_name, country FROM apps
WHERE id=1;
SQL CREATE TABLE 实例
现在我们想要创建一个名为 “Persons” 的表,包含五列:PersonID、LastName、FirstName、Address 和 City。
我们使用下面的 CREATE TABLE 语句:
实例
CREATE TABLE Persons
(
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);
PersonID 列的数据类型是 int,包含整数。
LastName、FirstName、Address 和 City 列的数据类型是 varchar,包含字符,且这些字段的最大长度为 255 个字符。
SQL CREATE TABLE + CONSTRAINT 语法
CREATE TABLE table_name
(
column_name1 data_type(size) constraint_name,
column_name2 data_type(size) constraint_name,
column_name3 data_type(size) constraint_name,
....
);
在 SQL 中,我们有如下约束:
NOT NULL - 指示某列不能存储 NULL 值。
UNIQUE - 保证某列的每行必须有唯一的值。
PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK - 保证列中的值符合指定的条件。
DEFAULT - 规定没有给列赋值时的默认值。
PRIMARY KEY 约束的实例
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) //PRIMARY KEY约束
)
CREATE TABLE Persons
(
Id_P int NOT NULL PRIMARY KEY, //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
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)
注释:在上面的实例中,只有一个主键 PRIMARY KEY(pk_PersonID)。
然而,pk_PersonID 的值是由两个列(P_Id 和 LastName)组成的。
foreign key 用法:
create table if not exists per(
id bigint auto_increment comment '主键',
name varchar(20) not null comment '人员姓名',
work_id bigint not null comment '工作id',
create_time date default '2021-04-02',
primary key(id),
foreign key(work_id) references work(id)
)
create table if not exists work(
id bigint auto_increment comment '主键',
name varchar(20) not null comment '工作名称',
create_time date default '2021-04-02',
primary key(id)
)
添加 NOT NULL 约束
在一个已创建的表的 “Age” 字段中添加 NOT NULL 约束如下所示:
实例
ALTER TABLE Persons
MODIFY Age int NOT NULL;
删除 NOT NULL 约束
在一个已创建的表的 “Age” 字段中删除 NOT NULL 约束如下所示:
实例
ALTER TABLE Persons
MODIFY Age int NULL;
ALTER TABLE 时的 SQL UNIQUE 约束
当表已被创建时,如需在 “P_Id” 列创建 UNIQUE 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD UNIQUE (P_Id)
如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)
撤销 UNIQUE 约束
如需撤销 UNIQUE 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Persons
DROP INDEX uc_PersonID
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT uc_PersonID
CREATE TABLE 时的 SQL FOREIGN KEY 约束
下面的 SQL 在 “Orders” 表创建时在 “P_Id” 列上创建 FOREIGN KEY 约束:
MySQL:
```sql
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
)
SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL PRIMARY KEY,
OrderNo int NOT NULL,
P_Id int FOREIGN KEY REFERENCES Persons(P_Id)
)
如需命名 FOREIGN KEY 约束,并定义多个列的 FOREIGN KEY 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
ALTER TABLE 时的 SQL FOREIGN KEY 约束
当 “Orders” 表已被创建时,如需在 “P_Id” 列创建 FOREIGN KEY 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
如需命名 FOREIGN KEY 约束,并定义多个列的 FOREIGN KEY 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Orders
ADD CONSTRAINT fk_PerOrders
FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
撤销 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
下面的 SQL 在 “Persons” 表创建时在 “City” 列上创建 DEFAULT 约束:
My SQL / SQL Server / Oracle / MS Access:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'Sandnes'
)
通过使用类似 GETDATE() 这样的函数,DEFAULT 约束也可以用于插入系统值:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
OrderDate date DEFAULT GETDATE()
)
ALTER TABLE 时的 SQL DEFAULT 约束
当表已被创建时,如需在 “City” 列创建 DEFAULT 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Persons
ALTER City SET DEFAULT 'SANDNES'
SQL Server / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT ab_c DEFAULT 'SANDNES' for City
Oracle:
ALTER TABLE Persons
MODIFY City 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
索引
您可以在表中创建索引,以便更加快速高效地查询数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
注释:更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。
SQL CREATE INDEX 语法
在表上创建一个简单的索引。允许使用重复的值:
CREATE INDEX index_name
ON table_name (column_name)
SQL CREATE UNIQUE INDEX 语法
在表上创建一个唯一的索引。不允许使用重复的值:唯一的索引意味着两个行不能拥有相同的索引值。Creates a unique index on a table. Duplicate values are not allowed:
CREATE UNIQUE INDEX index_name
ON table_name (column_name)
注释:用于创建索引的语法在不同的数据库中不一样。因此,检查您的数据库中创建索引的语法。
CREATE INDEX 实例
下面的 SQL 语句在 “Persons” 表的 “LastName” 列上创建一个名为 “PIndex” 的索引:
CREATE INDEX PIndex
ON Persons (LastName)
如果您希望索引不止一个列,您可以在括号中列出这些列的名称,用逗号隔开:
CREATE INDEX PIndex
ON Persons (LastName, FirstName)
用于 SQL Server 的语法
下面的 SQL 语句把 “Persons” 表中的 “ID” 列定义为 auto-increment 主键字段:
CREATE TABLE Persons
(
ID int IDENTITY(1,1) PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
MS SQL Server 使用 IDENTITY 关键字来执行 auto-increment 任务。
在上面的实例中,IDENTITY 的开始值是 1,每条新记录递增 1。
提示:要规定 "ID" 列以 10 起始且递增 5,请把 identity 改为 IDENTITY(10,5)。
要在 “Persons” 表中插入新记录,我们不必为 “ID” 列规定值(会自动添加一个唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen')
上面的 SQL 语句会在 “Persons” 表中插入一条新记录。“ID” 列会被赋予一个唯一的值。“FirstName” 列会被设置为 “Lars”,“LastName” 列会被设置为 “Monsen”。
用于 Access 的语法
下面的 SQL 语句把 “Persons” 表中的 “ID” 列定义为 auto-increment 主键字段:
CREATE TABLE Persons
(
ID Integer 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。
提示:要规定 "ID" 列以 10 起始且递增 5,请把 autoincrement 改为 AUTOINCREMENT(10,5)。
要在 "Persons" 表中插入新记录,我们不必为 "ID" 列规定值(会自动添加一个唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen')
上面的 SQL 语句会在 "Persons" 表中插入一条新记录。"ID" 列会被赋予一个唯一的值。"FirstName" 列会被设置为 "Lars","LastName" 列会被设置为 "Monsen"。
auto-increment用于 Oracle 的语法
在 Oracle 中,代码稍微复杂一点。
您必须通过 sequence 对象(该对象生成数字序列)创建 auto-increment 字段。
请使用下面的 CREATE SEQUENCE 语法:
CREATE SEQUENCE seq_person
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10
上面的代码创建一个名为 seq_person 的 sequence 对象,它以 1 起始且以 1 递增。该对象缓存 10 个值以提高性能。cache 选项规定了为了提高访问速度要存储多少个序列值。
要在 “Persons” 表中插入新记录,我们必须使用 nextval 函数(该函数从 seq_person 序列中取回下一个值):
INSERT INTO Persons (ID,FirstName,LastName)
VALUES (seq_person.nextval,'Lars','Monsen')
上面的 SQL 语句会在 "Persons" 表中插入一条新记录。"ID" 列会被赋值为来自 seq_person 序列的下一个数字。"FirstName"列 会被设置为 "Lars","LastName" 列会被设置为 "Monsen"。