SQL SELECT 语句
SELECT 语句用于从数据库中选取数据。
结果被存储在一个结果表中,称为结果集。
SQL SELECT 语法
SELECT column1, column2, ...
FROM table_name;
与
SELECT * FROM table_name;
参数说明:
- column1, column2, …:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
SQL SELECT DISTINCT 语句
在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。
DISTINCT 关键词用于返回唯一不同的值。
SQL SELECT DISTINCT 语法
SELECT DISTINCT column1, column2, ...
FROM table_name;
参数说明:
- column1, column2, …:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
下面的 SQL 语句仅从 “Websites” 表的 “country” 列中选取唯一不同的值,也就是去掉 “country” 列重复值:
实例
SELECT DISTINCT country FROM Websites;
SQL WHERE 子句
WHERE 子句用于提取那些满足指定条件的记录。
SQL WHERE 语法
SELECT column1, column2, ...
FROM table_name
WHERE condition;
参数说明:
- column1, column2, …:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
WHERE 子句中的运算符
下面的运算符可以在 WHERE 子句中使用:
运算符 | 描述 |
---|---|
= | 等于 |
<> | 不等于。注释:在 SQL 的一些版本中,该操作符可被写成 != |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN | 在某个范围内 |
LIKE | 搜索某种模式 |
IN | 指定针对某个列的多个可能值 |
SQL AND & OR 运算符
如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。
AND 运算符实例
下面的 SQL 语句从 “Websites” 表中选取国家为 “CN” 且alexa排名大于 “50” 的所有网站:
SELECT * FROM Websites
WHERE country='CN'
AND alexa > 50;
OR 运算符实例
下面的 SQL 语句从 “Websites” 表中选取国家为 “USA” 或者 “CN” 的所有客户:
SELECT * FROM Websites
WHERE country='USA'
OR country='CN';
结合 AND & OR
您也可以把 AND 和 OR 结合起来(使用圆括号来组成复杂的表达式)。
下面的 SQL 语句从 “Websites” 表中选取 alexa 排名大于 “15” 且国家为 “CN” 或 “USA” 的所有网站:
SELECT * FROM Websites
WHERE alexa > 15
AND (country='CN' OR country='USA');
SQL ORDER BY 关键字
ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。
ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序,您可以使用 DESC 关键字。
SQL ORDER BY 语法
SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC|DESC;
- column1, column2, …:要排序的字段名称,可以为多个字段。
- ASC:表示按升序排序。
- DESC:表示按降序排序。
ORDER BY 实例
下面的 SQL 语句从 “Websites” 表中选取所有网站,并按照 “alexa” 列排序:
SELECT * FROM Websites
ORDER BY alexa;
ORDER BY DESC 实例
下面的 SQL 语句从 “Websites” 表中选取所有网站,并按照 “alexa” 列降序排序:
SELECT * FROM Websites
ORDER BY alexa DESC;
ORDER BY 多列
下面的 SQL 语句从 “Websites” 表中选取所有网站,并按照 “country” 和 “alexa” 列排序:
SELECT * FROM Websites
ORDER BY country,alexa;
SQL INSERT INTO 语句
INSERT INTO 语句用于向表中插入新记录。
SQL INSERT INTO 语法
INSERT INTO 语句可以有两种编写形式。
第一种形式无需指定要插入数据的列名,只需提供被插入的值即可:
INSERT INTO table_name
VALUES (value1,value2,value3,...);
第二种形式需要指定列名及被插入的值:
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
参数说明:
- table_name:需要插入新记录的表名。
- column1, column2, …:需要插入的字段名。
- value1, value2, …:需要插入的字段值。
INSERT INTO 实例
假设我们要向 “Websites” 表中插入一个新行。
我们可以使用下面的 SQL 语句:
INSERT INTO Websites (name, url, alexa, country)
VALUES ('百度','https://www.vanforever.com/','4','CN');
在指定的列插入数据
我们也可以在指定的列插入数据。
下面的 SQL 语句将插入一个新行,但是只在 “name”、”url” 和 “country” 列插入数据(id 字段会自动更新):
INSERT INTO Websites (name, url, country)
VALUES ('stackoverflow', 'http://stackoverflow.com/', 'IND');
SQL UPDATE 语句
UPDATE 语句用于更新表中已存在的记录。
SQL UPDATE 语法
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
参数说明:
- table_name:要修改的表名称。
- column1, column2, …:要修改的字段名称,可以为多个字段。
- value1, value2, …:要修改的值,可以为多个值。
- condition:修改条件,用于指定哪些数据要修改。
SQL UPDATE 实例
假设我们要把 “NIIT教程” 的 alexa 排名更新为 5000,country 改为 USA。
我们使用下面的 SQL 语句:
UPDATE Websites SET alexa='5000', country='USA'
WHERE name='NIIT教程';
Update 警告!
在更新记录时要格外小心!在上面的实例中,如果我们省略了 WHERE 子句,如下所示:
UPDATE Websites
SET alexa='5000', country='USA'
执行以上代码会将 Websites 表中所有数据的 alexa 改为 5000,country 改为 USA。
执行没有 WHERE 子句的 UPDATE 要慎重,再慎重。
SQL DELETE 语句
DELETE 语句用于删除表中的行。
SQL DELETE 语法
DELETE FROM table_name
WHERE condition;
参数说明:
- table_name:要删除的表名称。
- condition:删除条件,用于指定哪些数据要删除。
SQL DELETE 实例
假设我们要从 “Websites” 表中删除网站名为 “Facebook” 且国家为 USA 的网站。
我们使用下面的 SQL 语句:
DELETE FROM Websites
WHERE name='Facebook'
AND country='USA';
SQL SELECT TOP 子句
SELECT TOP 子句用于规定要返回的记录的数目。
SELECT TOP 子句对于拥有数千条记录的大型表来说,是非常有用的。
MySQL 语法
SELECT column_name(s)
FROM table_name
LIMIT number;
MySQL SELECT LIMIT 实例
下面的 SQL 语句从 “Websites” 表中选取头两条记录:
SELECT * FROM Websites
LIMIT 2;
SQL SELECT TOP PERCENT 实例
在 Microsoft SQL Server 中还可以使用百分比作为参数。
下面的 SQL 语句从 websites 表中选取前面百分之 50 的记录:
以下操作在 Microsoft SQL Server 数据库中可执行。
SELECT TOP 50 PERCENT * FROM Websites;
注意:在mysql中不支持top关键字,而采用limit关键字进行代替
SQL LIKE 操作符
LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。
SQL LIKE 语法
SELECT column1, column2, ...
FROM table_name
WHERE column LIKE pattern;
参数说明:
- column1, column2, …:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
- column:要搜索的字段名称。
- pattern:搜索模式。
SQL LIKE 操作符实例
下面的 SQL 语句选取 name 以字母 “G” 开始的所有客户:
SELECT * FROM Websites
WHERE name LIKE 'G%';
下面的 SQL 语句选取 name 以字母 “k” 结尾的所有客户:
SELECT * FROM Websites
WHERE name LIKE '%k';
下面的 SQL 语句选取 name 包含模式 “oo” 的所有客户:
SELECT * FROM Websites
WHERE name LIKE '%oo%';
通过使用 NOT 关键字,您可以选取不匹配模式的记录。
下面的 SQL 语句选取 name 不包含模式 “oo” 的所有客户:
SELECT * FROM Websites
WHERE name NOT LIKE '%oo%';
SQL 通配符
在 SQL 中,通配符与 SQL LIKE 操作符一起使用。
SQL 通配符用于搜索表中的数据。
在 SQL 中,可使用以下通配符:
通配符 | 描述 |
---|---|
% | 替代 0 个或多个字符 |
_ | 替代一个字符 |
[charlist] | 字符列中的任何单一字符 |
[^charlist] 或 [!charlist] | 不在字符列中的任 |
使用 SQL % 通配符
下面的 SQL 语句选取 url 以字母 “https” 开始的所有网站:
SELECT * FROM Websites
WHERE url LIKE 'https%';
下面的 SQL 语句选取 url 包含模式 “oo” 的所有网站:
SELECT * FROM Websites
WHERE url LIKE '%oo%';
使用 SQL _ 通配符
下面的 SQL 语句选取 name 以一个任意字符开始,然后是 “oogle” 的所有客户:
SELECT * FROM Websites
WHERE name LIKE '_oogle';
下面的 SQL 语句选取 name 以 “G” 开始,然后是一个任意字符,然后是 “o”,然后是一个任意字符,然后是 “le” 的所有网站:
SELECT * FROM Websites
WHERE name LIKE 'G_o_le';
使用 SQL [charlist] 通配符
MySQL 中使用 REGEXP 或 NOT REGEXP 运算符 (或 RLIKE 和 NOT RLIKE) 来操作正则表达式。
下面的 SQL 语句选取 name 以 “G”、”F” 或 “s” 开始的所有网站:
SELECT * FROM Websites
WHERE name REGEXP '^[GFs]';
下面的 SQL 语句选取 name 以 A 到 H 字母开头的网站:
SELECT * FROM Websites
WHERE name REGEXP '^[A-H]';
下面的 SQL 语句选取 name 不以 A 到 H 字母开头的网站:
SELECT * FROM Websites
WHERE name REGEXP '^[^A-H]';
IN 操作符
IN 操作符允许您在 WHERE 子句中规定多个值。
SQL IN 语法
SELECT column1, column2, ...
FROM table_name
WHERE column IN (value1, value2, ...);
参数说明:
- column1, column2, …:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
- column:要查询的字段名称。
- value1, value2, …:要查询的值,可以为多个值。
IN 操作符实例
下面的 SQL 语句选取 name 为 “Google” 或 “Vanforever” 的所有网站:
SELECT * FROM Websites
WHERE name IN ('Google','Vanforever');
SQL BETWEEN 操作符
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
SQL BETWEEN 语法
SELECT column1, column2, ...
FROM table_name
WHERE column BETWEEN value1 AND value2;
参数说明:
- column1, column2, …:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
- column:要查询的字段名称。
- value1:范围的起始值。
- value2:范围的结束值。
BETWEEN 操作符实例
下面的 SQL 语句选取 alexa 介于 1 和 20 之间的所有网站:
SELECT * FROM Websites
WHERE alexa BETWEEN 1 AND 20;
NOT BETWEEN 操作符实例
如需显示不在上面实例范围内的网站,请使用 NOT BETWEEN:
SELECT * FROM Websites
WHERE alexa NOT BETWEEN 1 AND 20;
带有 IN 的 BETWEEN 操作符实例
下面的 SQL 语句选取 alexa 介于 1 和 20 之间但 country 不为 USA 和 IND 的所有网站:
SELECT * FROM Websites
WHERE (alexa BETWEEN 1 AND 20)
AND country NOT IN ('USA', 'IND');
带有文本值的 BETWEEN 操作符实例
下面的 SQL 语句选取 name 以介于 ‘A’ 和 ‘H’ 之间字母开始的所有网站:
SELECT * FROM Websites
WHERE name BETWEEN 'A' AND 'H';
带有文本值的 NOT BETWEEN 操作符实例
下面的 SQL 语句选取 name 不介于 ‘A’ 和 ‘H’ 之间字母开始的所有网站:
SELECT * FROM Websites
WHERE name NOT BETWEEN 'A' AND 'H';
带有日期值的 BETWEEN 操作符实例
下面的 SQL 语句选取 date 介于 ‘2016-05-10’ 和 ‘2016-05-14’ 之间的所有访问记录:
SELECT * FROM access_log
WHERE date BETWEEN '2016-05-10' AND '2016-05-14';
SQL 别名
通过使用 SQL,可以为表名称或列名称指定别名。
基本上,创建别名是为了让列名称的可读性更强。
列的 SQL 别名语法
SELECT column_name AS alias_name
FROM table_name;
表的 SQL 别名语法
SELECT column_name(s)
FROM table_name AS alias_name;
列的别名实例
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。提示:如果列名称包含空格,要求使用双引号或方括号:
SELECT name AS n, country AS c
FROM Websites;
在下面的 SQL 语句中,我们把三个列(url、alexa 和 country)结合在一起,并创建一个名为 “site_info” 的别名:
SELECT name, CONCAT(url, ', ', alexa, ', ', country) AS site_info
FROM Websites;
表的别名实例
下面的 SQL 语句选取 “Baidu” 的所有访问记录。我们使用 “Websites” 和 “access_log” 表,并分别为它们指定表别名 “w” 和 “a”(通过使用别名让 SQL 更简短):
SELECT w.name, w.url, a.count, a.date
FROM Websites AS w, access_log AS a
WHERE a.site_id=w.id and w.name="Baidu";
不带别名的相同的 SQL 语句:
SELECT Websites.name, Websites.url, access_log.count, access_log.date
FROM Websites, access_log
WHERE Websites.id=access_log.site_id and Websites.name="Baidu";
在下面的情况下,使用别名很有用:
- 在查询中涉及超过一个表
- 在查询中使用了函数
- 列名称很长或者可读性差
- 需要把两个列或者多个列结合在一起
SQL JOIN
SQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。
下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。
最常见的 JOIN 类型:SQL INNER JOIN(简单的 JOIN)。 SQL INNER JOIN 从多个表中返回满足 JOIN 条件的所有行。
语法:
SELECT column1, column2, ...
FROM table1
JOIN table2 ON condition;
参数说明:
- column1, column2, …:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table1:要连接的第一个表。
- table2:要连接的第二个表。
- condition:连接条件,用于指定连接方式。
下面是选自 “Websites” 表的数据:
id | name | url | alexa | country |
---|---|---|---|---|
1 | https://www.google.cm/ | 1 | USA | |
2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
3 | vanforever | https://www.vanforever.com.cn/ | 4689 | CN |
4 | 微博 | http://weibo.com/ | 20 | CN |
5 | https://www.facebook.com/ | 3 | USA | |
6 | stackoverflow | http://stackoverflow.com/ | 0 | IND |
下面是 “access_log” 网站访问记录表的数据:
aid | site_id | count | date |
---|---|---|---|
1 | 1 | 45 | 2024-05-10 |
2 | 3 | 100 | 2024-05-13 |
3 | 1 | 230 | 2024-05-14 |
4 | 2 | 10 | 2024-05-14 |
5 | 5 | 205 | 2024-05-14 |
6 | 4 | 13 | 2024-05-15 |
7 | 3 | 220 | 2024-05-15 |
8 | 5 | 545 | 2024-05-16 |
9 | 3 | 201 | 2024-05-17 |
请注意,”Websites” 表中的 “id” 列指向 “access_log” 表中的字段 “site_id“。上面这两个表是通过 “site_id” 列联系起来的。
然后,如果我们运行下面的 SQL 语句(包含 INNER JOIN):
SELECT Websites.id, Websites.name, access_log.count, access_log.date
FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id;
执行以上 SQL 输出结果如下:
SQL INNER JOIN 关键字
INNER JOIN 关键字在表中存在至少一个匹配时返回行。
SQL INNER JOIN 语法
SELECT *column_name(s)*
FROM *table1*
INNER JOIN *table2*
ON *table1.column_name*=*table2.column_name*;
或:
SELECT *column_name(s)*
FROM *table1*
JOIN *table2*
ON *table1.column_name*=*table2.column_name*;
参数说明:
- columns:要显示的列名。
- table1:表1的名称。
- table2:表2的名称。
- column_name:表中用于连接的列名。
注释:INNER JOIN 与 JOIN 是相同的。
SQL INNER JOIN 实例
下面的 SQL 语句将返回所有网站的访问记录:
SELECT Websites.name, access_log.count, access_log.date
FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id
ORDER BY access_log.count;
SQL LEFT JOIN 关键字
LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。
SQL LEFT JOIN 语法
SELECT *column_name(s)*
FROM *table1*
LEFT JOIN *table2*
ON *table1.column_name*=*table2.column_name*;
或:
SELECT *column_name(s)*
FROM *table1*
LEFT OUTER JOIN *table2*
ON *table1.column_name*=*table2.column_name*;
SQL LEFT JOIN 实例
下面的 SQL 语句将返回所有网站及他们的访问量(如果有的话)。
以下实例中我们把 Websites 作为左表,access_log 作为右表:
SELECT Websites.name, access_log.count, access_log.date
FROM Websites
LEFT JOIN access_log
ON Websites.id=access_log.site_id
ORDER BY access_log.count DESC;
SQL RIGHT JOIN 关键字
RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。
SQL RIGHT JOIN 语法
SELECT *column_name(s)*
FROM *table1*
RIGHT JOIN *table2*
ON *table1.column_name*=*table2.column_name*;
或:
SELECT *column_name(s)*
FROM *table1*
RIGHT OUTER JOIN *table2*
ON *table1.column_name*=*table2.column_name*;
SQL RIGHT JOIN 实例
下面的 SQL 语句将返回网站的访问记录。
以下实例中我们把 Websites 作为左表,access_log 作为右表:
SELECT websites.name, access_log.count, access_log.date
FROM websites
RIGHT JOIN access_log
ON access_log.site_id=websites.id
ORDER BY access_log.count DESC;
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 语句中的列名。
下面是选自 “Websites” 表的数据:
id | name | url | alexa | country |
---|---|---|---|---|
1 | https://www.google.cm/ | 1 | USA | |
2 | 淘宝 | https://www.taobao.com/ | 13 | CN |
3 | vanforever | https://www.vanforever.com.cn/ | 4689 | CN |
4 | 微博 | http://weibo.com/ | 20 | CN |
5 | https://www.facebook.com/ | 3 | USA | |
6 | stackoverflow | http://stackoverflow.com/ | 0 | IND |
下面是 “apps” APP 的数据:
id | app_name | url | country |
---|---|---|---|
1 | QQ APP | http://im.qq.com/ | CN |
2 | 微博 APP | http://weibo.com/ | CN |
3 | 淘宝 APP | https://www.taobao.com/ | CN |
SQL UNION 实例
下面的 SQL 语句从 “Websites” 和 “apps” 表中选取所有不同的country(只有不同的值):
SELECT country FROM Websites
UNION
SELECT country FROM apps
ORDER BY country;
注释:UNION 不能用于列出两个表中所有的country。如果一些网站和APP来自同一个国家,每个国家只会列出一次。UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!
SQL UNION ALL 实例
下面的 SQL 语句使用 UNION ALL 从 “Websites” 和 “apps” 表中选取所有的country(也有重复的值):
SELECT country FROM Websites
UNION ALL
SELECT country FROM apps
ORDER BY country;
SQL SELECT INTO 语句
SELECT INTO 语句从一个表复制数据,然后把数据插入到另一个新表中。
注意:
MySQL 数据库不支持 SELECT … INTO 语句,但支持INSERT INTO … SELECT
当然你可以使用以下语句来拷贝表结构及数据:
CREATE TABLE 新表 AS SELECT * FROM 旧表
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 DATABASE 语句
CREATE DATABASE 语句用于创建数据库。
SQL CREATE DATABASE 语法
CREATE DATABASE dbname;
SQL CREATE DATABASE 实例
下面的 SQL 语句创建一个名为 “my_db” 的数据库:
CREATE DATABASE my_db;
数据库表可以通过 CREATE TABLE 语句来添加。
SQL CREATE TABLE 语句
CREATE TABLE 语句用于创建数据库中的表。
表由行和列组成,每个表都必须有个表名。
SQL CREATE TABLE 语法
CREATE TABLE *table_name*
(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
....
);
column_name 参数规定表中列的名称。
data_type 参数规定列的数据类型(例如 varchar、integer、decimal、date 等等)。
size 参数规定表中列的最大长度。
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)
);
SQL 约束(Constraints)
SQL 约束用于规定表中的数据规则。
如果存在违反约束的数据行为,行为会被约束终止。
约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。
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 – 规定没有给列赋值时的默认值。
SQL NOT NULL 约束
NOT NULL 约束强制列不接受 NULL 值。
NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
下面的 SQL 强制 “ID” 列、 “LastName” 列以及 “FirstName” 列不接受 NULL 值:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255) NOT NULL,
Age int
);
添加 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;
SQL UNIQUE 约束
UNIQUE 约束唯一标识数据库表中的每条记录。
UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。
PRIMARY KEY 约束拥有自动定义的 UNIQUE 约束。
请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。
CREATE TABLE 时的 SQL UNIQUE 约束
下面的 SQL 在 “Persons” 表创建时在 “P_Id” 列上创建 UNIQUE 约束:
MySQL:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (P_Id)
)
如需命名 UNIQUE 约束,并定义多个列的 UNIQUE 约束,请使用下面的 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 uc_PersonID UNIQUE (P_Id,LastName)
)
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 PRIMARY KEY 约束
PRIMARY KEY 约束唯一标识数据库表中的每条记录。
主键必须包含唯一的值。
主键列不能包含 NULL 值。
每个表都应该有一个主键,并且每个表只能有一个主键。
CREATE TABLE 时的 SQL PRIMARY KEY 约束
下面的 SQL 在 “Persons” 表创建时在 “P_Id” 列上创建 PRIMARY KEY 约束:
MySQL:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (P_Id)
)
如需命名 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)组成的。
ALTER TABLE 时的 SQL PRIMARY KEY 约束
当表已被创建时,如需在 “P_Id” 列创建 PRIMARY KEY 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD PRIMARY KEY (P_Id)
如需命名 PRIMARY KEY 约束,并定义多个列的 PRIMARY KEY 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
注释:如果您使用 ALTER TABLE 语句添加主键,必须把主键列声明为不包含 NULL 值(在表首次创建时)。
撤销 PRIMARY KEY 约束
如需撤销 PRIMARY KEY 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Persons
DROP PRIMARY KEY
SQL FOREIGN KEY 约束
一个表中的 FOREIGN KEY 指向另一个表中的 UNIQUE KEY(唯一约束的键)。
让我们通过一个实例来解释外键。请看下面两个表:
“Persons” 表:
P_Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Hansen | Ola | Timoteivn 10 | Sandnes |
2 | Svendson | Tove | Borgvn 23 | Sandnes |
3 | Pettersen | Kari | Storgt 20 | Stavanger |
“Orders” 表:
O_Id | OrderNo | P_Id |
---|---|---|
1 | 77895 | 3 |
2 | 44678 | 3 |
3 | 22456 | 2 |
4 | 24562 | 1 |
请注意,”Orders” 表中的 “P_Id” 列指向 “Persons” 表中的 “P_Id” 列。
“Persons” 表中的 “P_Id” 列是 “Persons” 表中的 PRIMARY KEY。
“Orders” 表中的 “P_Id” 列是 “Orders” 表中的 FOREIGN KEY。
FOREIGN KEY 约束用于预防破坏表之间连接的行为。
FOREIGN KEY 约束也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
CREATE TABLE 时的 SQL FOREIGN KEY 约束
下面的 SQL 在 “Orders” 表创建时在 “P_Id” 列上创建 FOREIGN KEY 约束:
MySQL:
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)
如需命名 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 CHECK 约束
CHECK 约束用于限制列中的值的范围。
如果对单个列定义 CHECK 约束,那么该列只允许特定的值。
如果对一个表定义 CHECK 约束,那么此约束会基于行中其他列的值在特定的列中对值进行限制。
CREATE TABLE 时的 SQL CHECK 约束
下面的 SQL 在 “Persons” 表创建时在 “P_Id” 列上创建 CHECK 约束。CHECK 约束规定 “P_Id” 列必须只包含大于 0 的整数。
MySQL:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CHECK (P_Id>0)
)
如需命名 CHECK 约束,并定义多个列的 CHECK 约束,请使用下面的 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 chk_Person CHECK (P_Id>0 AND City='Sandnes')
)
ALTER TABLE 时的 SQL CHECK 约束
当表已被创建时,如需在 “P_Id” 列创建 CHECK 约束,请使用下面的 SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CHECK (P_Id>0)
如需命名 CHECK 约束,并定义多个列的 CHECK 约束,请使用下面的 SQL 语法:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')
撤销 CHECK 约束
如需撤销 CHECK 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Persons
DROP CHECK chk_Person
SQL DEFAULT 约束
DEFAULT 约束用于向列中插入默认值。
如果没有规定其他的值,那么会将默认值添加到所有的新记录。
CREATE TABLE 时的 SQL DEFAULT 约束
下面的 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'
撤销 DEFAULT 约束
如需撤销 DEFAULT 约束,请使用下面的 SQL:
MySQL:
ALTER TABLE Persons
ALTER City DROP DEFAULT
SQL CREATE INDEX 语句
CREATE INDEX 语句用于在表中创建索引。
在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
索引
您可以在表中创建索引,以便更加快速高效地查询数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
注释:更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。
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)
DROP INDEX 语句
索引是一种优化数据库查询性能的结构,但有时候可能需要删除某个索引,例如当索引不再需要或需要替换为新的索引时。
DROP INDEX 语句用于删除表中的索引。
语法格式:
DROP INDEX [IF EXISTS] index_name
ON TABLE_NAME;
参数说明:
DROP INDEX
:表示要删除索引的操作。IF EXISTS
:是一个可选的子句,用于检查索引是否存在。如果存在,就执行删除操作;如果不存在,不会报错。index_name
:要删除的索引的名称。ON table_name
:指定包含要删除索引的表的名称。
以下是一个简单的例子,假设有一个名为 idx_example 的索引要从名为 my_table 的表中删除:
DROP INDEX IF EXISTS idx_example
ON my_table;
请注意,删除索引可能会影响数据库的查询性能,因此在执行此类操作之前,请确保了解其对数据库的影响,并根据实际需求进行操作。
DROP TABLE 语句
DROP TABLE 语句用于删除表。
删除表将同时删除表的结构以及存储在其中的所有数据。因此,在执行DROP TABLE语句之前,请确保您真的希望永久删除表及其所有数据,因为此操作是不可逆的。
语法格式:
DROP TABLE [IF EXISTS] TABLE_NAME;
参数说明:
DROP TABLE
:表示删除表的操作。IF EXISTS
:是一个可选的子句,用于检查表是否存在。如果存在,执行删除操作;如果不存在,不会报错。table_name
:要删除的表的名称。
以下是一个简单的例子,假设要删除名为 my_table 的表:
DROP TABLE IF EXISTS my_table;
请注意,执行DROP TABLE将永久删除表和其所有数据。在执行此类操作之前,请确保您已备份重要的数据,并且您有删除表的权限。
DROP DATABASE 语句
DROP DATABASE 语句用于删除数据库,包括其中的所有表、视图、存储过程等数据库对象。
DROP DATABASE 是一个非常强大和危险的操作,因为它会永久删除整个数据库及其所有相关数据,因此在执行之前务必要慎重考虑并确保你真的希望执行此操作。
语法格式:
DROP DATABASE [IF EXISTS] database_name;
参数说明:
DROP DATABASE
:表示删除数据库的操作。IF EXISTS
:是一个可选的子句,用于检查数据库是否存在。如果存在,执行删除操作;如果不存在,不会报错。database_name
:要删除的数据库的名称。
以下是一个简单的例子,假设要删除名为 my_database 的数据库:
DROP DATABASE IF EXISTS my_database;
在执行 DROP DATABASE 之前,请确保你已经备份了数据库中的重要数据,并且你确实有权限执行这个操作,因为删除数据库通常需要管理员或超级用户的权限。此外,执行此类操作之前最好先确认没有其他用户正在使用该数据库。
TRUNCATE TABLE 语句
如果我们仅仅需要删除表内的数据,但并不删除表本身,那么我们该如何做呢?
在 SQL 中,TRUNCATE TABLE语句用于快速删除表中的所有数据,但保留表的结构(列、约束等),与 DELETE 语句相比,TRUNCATE TABLE 通常更快,因为它是通过删除表中的所有行而不是逐行删除实现的。
然而,需要注意的是,TRUNCATE TABLE不会触发触发器,而且无法在事务中进行回滚。
请使用 TRUNCATE TABLE 语句:
语法格式:
TRUNCATE TABLE TABLE_NAME;
参数说明:
TRUNCATE TABLE
:表示清空表的操作。table_name
:要清空的表的名称。
以下是一个简单的例子,假设要清空名为 my_table 的表:
TRUNCATE TABLE my_table;
当使用 TRUNCATE TABLE 清除数据时,表的主键自增值将被重置为默认的起始值,通常是从 1 开始。这意味着下一次插入数据时,主键将从 1 开始递增。与之不同的是,使用 DELETE 语句删除数据并不会重置主键自增值,而是保留当前的自增值。
ALTER TABLE 语句
ALTER TABLE 语句用于在已有的表中添加、删除或修改列。
SQL ALTER TABLE 语法
如需在表中添加列,请使用下面的语法:
ALTER TABLE table_name
ADD column_name datatype
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
ALTER TABLE table_name
DROP COLUMN column_name
要改变表中列的数据类型,请使用下面的语法:
My SQL / Oracle:
ALTER TABLE table_name
MODIFY COLUMN column_name datatype
SQL ALTER TABLE 实例
请看 “Persons” 表:
P_Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Hansen | Ola | Timoteivn 10 | Sandnes |
2 | Svendson | Tove | Borgvn 23 | Sandnes |
3 | Pettersen | Kari | Storgt 20 | Stavanger |
现在,我们想在 “Persons” 表中添加一个名为 “DateOfBirth” 的列。
我们使用下面的 SQL 语句:
ALTER TABLE Persons
ADD DateOfBirth date
现在,”Persons” 表将如下所示:
P_Id | LastName | FirstName | Address | City | DateOfBirth |
---|---|---|---|---|---|
1 | Hansen | Ola | Timoteivn 10 | Sandnes | |
2 | Svendson | Tove | Borgvn 23 | Sandnes | |
3 | Pettersen | Kari | Storgt 20 | Stavanger |
改变数据类型实例
现在,我们想要改变 “Persons” 表中 “DateOfBirth” 列的数据类型。
我们使用下面的 SQL 语句:
ALTER TABLE Persons
ALTER COLUMN DateOfBirth year
请注意,现在 “DateOfBirth” 列的类型是 year,可以存放 2 位或 4 位格式的年份。
DROP COLUMN 实例
接下来,我们想要删除 “Person” 表中的 “DateOfBirth” 列。
我们使用下面的 SQL 语句:
ALTER TABLE Persons
DROP COLUMN DateOfBirth
现在,”Persons” 表将如下所示:
P_Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Hansen | Ola | Timoteivn 10 | Sandnes |
2 | Svendson | Tove | Borgvn 23 | Sandnes |
3 | Pettersen | Kari | Storgt 20 | Stavanger |
AUTO INCREMENT 字段
我们通常希望在每次插入新记录时,自动地创建主键字段的值。
我们可以在表中创建一个 auto-increment 字段。
用于 MySQL 的语法
下面的 SQL 语句把 “Persons” 表中的 “ID” 列定义为 auto-increment 主键字段:
CREATE TABLE Persons
(
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (ID)
)
MySQL 使用 AUTO_INCREMENT 关键字来执行 auto-increment 任务。
默认地,AUTO_INCREMENT 的开始值是 1,每条新记录递增 1。
要让 AUTO_INCREMENT 序列以其他的值起始,请使用下面的 SQL 语法:
ALTER TABLE Persons AUTO_INCREMENT=100
要在 “Persons” 表中插入新记录,我们不必为 “ID” 列规定值(会自动添加一个唯一的值):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen')
上面的 SQL 语句会在 “Persons” 表中插入一条新记录。”ID” 列会被赋予一个唯一的值。”FirstName” 列会被设置为 “Lars”,”LastName” 列会被设置为 “Monsen”。
SQL CREATE VIEW 语句
在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。
视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。
您可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,也可以呈现数据,就像这些数据来自于某个单一的表一样。
SQL CREATE VIEW 语法
CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
参数说明:
- CREATE VIEW: 声明你要创建一个视图。
- view_name: 指定视图的名称。
- AS: 指定关键字,表示视图的定义开始。
- SELECT column1, column2, …: 指定视图中包含的列,可以是表中的列或计算列。
- FROM table_name: 指定视图从哪个表中获取数据。
- WHERE condition: 可选部分,用于指定筛选条件,限制视图中的行。
注释:视图总是显示最新的数据!每当用户查询视图时,数据库引擎通过使用视图的 SQL 语句重建数据。
SQL CREATE VIEW 实例
假设你有一个包含员工信息的表 employees,包括以下列:employee_id、first_name、last_name、salary 和 department_id,现在,我们将创建一个视图,显示工资高于某个阈值的员工信息。
实例如下:
-- 创建包含高工资员工信息的视图
CREATE VIEW high_salary_employees AS
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE salary > 50000;
在这个例子中,我们创建了一个名为 high_salary_employees 的视图,该视图包含了那些工资高于 50000 的员工的信息。
现在,你可以像查询普通表一样使用这个视图:
-- 查询高工资员工视图
SELECT *
FROM high_salary_employees;
这将返回所有工资高于 50000 的员工的详细信息,而不需要每次都编写相同的筛选条件。
值得注意的是,视图本质上是一个虚拟的表,它并不存储数据,而是基于基础表的查询结果生成。因此,如果基础表的数据发生变化,视图的内容也会相应地更新。
SQL 更新视图
在 SQL 中,你不能直接使用 UPDATE 语句来更新视图,因为视图是基于查询结果生成的虚拟表,而不是实际存储数据的表。
更新视图的实质是通过更新视图所基于的表中的数据,然后视图会反映这些变化。
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
其中,table_name 是基础表的名称,column1, column2, … 是要更新的列,value1, value2, … 是新的值,condition 是更新的条件。
现在,我们希望向 “Current Product List” 视图添加 “Category” 列。我们将通过下列 SQL 更新视图:
举例来说,如果你有一个名为 high_salary_employees 的视图,显示工资高于 50000 的员工信息,而这个视图基于 employees 表的查询结果,你可以通过以下步骤来更新数据:
-- 步骤 1: 更新 employees 表中的数据
UPDATE employees
SET salary = 60000
WHERE employee_id = 1001;
-- 步骤 2: 查询更新后的高工资员工视图
SELECT *
FROM high_salary_employees;
这样,你更新了 employees 表中的数据,而视图 high_salary_employees 将反映出这些变化。
SQL 撤销视图
在 SQL 中,撤销(或删除)视图是通过使用 DROP VIEW 语句来实现的。
DROP VIEW 语句用于从数据库中删除一个已存在的视图。语法如下:
DROP VIEW [IF EXISTS] view_name;
参数说明:
- DROP VIEW: 表示你要删除一个视图。
- IF EXISTS: 可选部分,用于检查视图是否存在。如果存在,则执行删除操作;如果不存在,不会发生错误。在某些数据库系统中,这是可选的。
- view_name: 指定要删除的视图的名称。
在执行以下语句后,视图 high_salary_employees 将被从数据库中删除。
-- 删除名为 high_salary_employees 的视图
DROP VIEW IF EXISTS high_salary_employees;
请注意,这并不影响基础表中的数据,只是删除了视图的定义。
如果你需要撤销或删除某个表中的数据,应该使用 DROP TABLE 语句。
在使用 DROP VIEW 语句时,请确保你真的想要删除该视图,因为一旦删除,将无法恢复视图的定义。
SQL 日期(Dates)
当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配。
只要您的数据包含的只是日期部分,运行查询就不会出问题。但是,如果涉及时间部分,情况就有点复杂了。
在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数。
MySQL Date 函数
下面的表格列出了 MySQL 中最重要的内建日期函数:
函数 | 描述 |
---|---|
NOW() | 返回当前的日期和时间 |
CURDATE() | 返回当前的日期 |
CURTIME() | 返回当前的时间 |
DATE() | 提取日期或日期/时间表达式的日期部分 |
EXTRACT() | 返回日期/时间的单独部分 |
DATE_ADD() | 向日期添加指定的时间间隔 |
DATE_SUB() | 从日期减去指定的时间间隔 |
DATEDIFF() | 返回两个日期之间的天数 |
DATE_FORMAT() | 用不同的格式显示日期/时间 |
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 日期处理
如果不涉及时间部分,那么我们可以轻松地比较两个日期!
假设我们有如下的 “Orders” 表:
OrderId | ProductName | OrderDate |
---|---|---|
1 | Geitost | 2008-11-11 |
2 | Camembert Pierrot | 2008-11-09 |
3 | Mozzarella di Giovanni | 2008-11-11 |
4 | Mascarpone Fabioli | 2008-10-29 |
现在,我们希望从上表中选取 OrderDate 为 “2008-11-11” 的记录。
我们使用下面的 SELECT 语句:
SELECT * FROM Orders WHERE OrderDate=’2008-11-11′
结果集如下所示:
OrderId | ProductName | OrderDate |
---|---|---|
1 | Geitost | 2008-11-11 |
3 | Mozzarella di Giovanni | 2008-11-11 |
现在,假设 “Orders” 表如下所示(请注意 “OrderDate” 列中的时间部分):
OrderId | ProductName | OrderDate |
---|---|---|
1 | Geitost | 2008-11-11 13:23:44 |
2 | Camembert Pierrot | 2008-11-09 15:45:21 |
3 | Mozzarella di Giovanni | 2008-11-11 11:12:01 |
4 | Mascarpone Fabioli | 2008-10-29 14:56:59 |
如果我们使用和上面一样的 SELECT 语句:
SELECT * FROM Orders WHERE OrderDate='2008-11-11'
或
SELECT * FROM Orders WHERE OrderDate='2008-11-11 00:00:00'
那么我们将得不到结果!因为表中没有”2008-11-11 00:00:00″日期。如果没有时间部分,默认时间为 00:00:00。
SQL NULL 值
如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。
NULL 值的处理方式与其他值不同。
NULL 用作未知的或不适用的值的占位符。
注释:无法比较 NULL 和 0;它们是不等价的。
SQL 的 NULL 值处理
请看下面的 “Persons” 表:
P_Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Hansen | Ola | Sandnes | |
2 | Svendson | Tove | Borgvn 23 | Sandnes |
3 | Pettersen | Kari | Stavanger |
假如 “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 |
---|---|---|
Hansen | Ola | |
Pettersen | Kari |
提示:请始终使用 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 |
---|---|---|
Svendson | Tove | Borgvn 23 |