0%

数据库基本操作

创建表

CREATE TABLE mytable (
int 类型,不为空,自增
id INT NOT NULL AUTO_INCREMENT,
int 类型,不可为空,默认值为 1,不为空
col1 INT NOT NULL DEFAULT 1,
变长字符串类型,最长为 45 个字符,可以为空
col2 VARCHAR(45) NULL,
日期类型,可为空
col3 DATE NULL,
设置主键为 id
PRIMARY KEY (id));

修改表

添加列

ALTER TABLE mytable
ADD col CHAR(20);
删除列

ALTER TABLE mytable
DROP COLUMN col;
删除表

DROP TABLE mytable;

插入

普通插入

INSERT INTO mytable(col1, col2)
VALUES(val1, val2);

插入检索出来的数据

INSERT INTO mytable1(col1, col2)
SELECT col1, col2
FROM mytable2;
将一个表的内容插入到一个新表

CREATE TABLE newtable AS
SELECT * FROM mytable;

更新

UPDATE mytable
SET col = val
WHERE id = 1;

删除

DELETE FROM mytable
WHERE id = 1;

TRUNCATE TABLE 可以清空表,也就是删除所有行。

TRUNCATE TABLE mytable;

查询

DISTINCT
相同值只会出现一次。它作用于所有列,也就是说所有列的值都相同才算相同。

SELECT DISTINCT col1, col2
FROM mytable;
LIMIT
限制返回的行数。可以有两个参数,第一个参数为起始行,从 0 开始;第二个参数为返回的总行数。

返回前 5 行:

SELECT *
FROM mytable
LIMIT 5;
SELECT *
FROM mytable
LIMIT 0, 5;
返回第 3 ~ 5 行:

SELECT *
FROM mytable
LIMIT 2, 3;

排序

ASC :升序(默认)
DESC :降序
可以按多个列进行排序,并且为每个列指定不同的排序方式:

SELECT *
FROM mytable
ORDER BY col1 DESC, col2 ASC;

先根据col1降序排序,再根据col2升序排序

过滤

不进行过滤的数据非常大,导致通过网络传输了多余的数据,从而浪费了网络带宽。因此尽量使用 SQL 语句来过滤不必要的数据,而不是传输所有的数据到客户端中然后由客户端进行过滤。

SELECT *
FROM mytable
WHERE col IS NULL;
下表显示了 WHERE 子句可用的操作符

操作符 说明
= 等于
< 小于

大于
<> != 不等于
<= !> 小于等于
= !< 大于等于
BETWEEN 在两个值之间
IS NULL 为 NULL 值
应该注意到,NULL 与 0、空字符串都不同。

AND 和 OR 用于连接多个过滤条件。优先处理 AND,当一个过滤表达式涉及到多个 AND 和 OR 时,可以使用 () 来决定优先级,使得优先级关系更清晰。

IN 操作符用于匹配一组值,其后也可以接一个 SELECT 子句,从而匹配子查询得到的一组值。

NOT 操作符用于否定一个条件。

通配符

通配符也是用在过滤语句中,但它只能用于文本字段。

% 匹配 >=0 个任意字符;

_ 匹配 ==1 个任意字符;

[ ] 可以匹配集合内的字符,例如 [ab] 将匹配字符 a 或者 b。用脱字符 ^ 可以对其进行否定,也就是不匹配集合内的字符。

使用 Like 来进行通配符匹配。

SELECT *
FROM mytable
WHERE col LIKE ‘[^AB]%’; – 不以 A 和 B 开头的任意文本
不要滥用通配符,通配符位于开头处匹配会非常慢。


计算字段

在数据库服务器上完成数据的转换和格式化的工作往往比客户端上快得多,并且转换和格式化后的数据量更少的话可以减少网络通信量。

计算字段通常需要使用 AS 来取别名,否则输出的时候字段名为计算表达式。

SELECT col1 * col2 AS alias
FROM mytable;
CONCAT() 用于连接两个字段。许多数据库会使用空格把一个值填充为列宽,因此连接的结果会出现一些不必要的空格,使用 TRIM() 可以去除首尾空格。

SELECT CONCAT(TRIM(col1), ‘(‘, TRIM(col2), ‘)’) AS concat_col
FROM mytable;

函数

各个 DBMS 的函数都是不相同的,因此不可移植,以下主要是 MySQL 的函数。

汇总
函 数 说 明
AVG() 返回某列的平均值
COUNT() 返回某列的行数
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和
AVG() 会忽略 NULL 行。

使用 DISTINCT 可以汇总不同的值。

SELECT AVG(DISTINCT col1) AS avg_col
FROM mytable;

分组

把具有相同的数据值的行放在同一组中。

可以对同一分组数据使用汇总函数进行处理,例如求分组数据的平均值等。

指定的分组字段除了能按该字段进行分组,也会自动按该字段进行排序。

SELECT col, COUNT() AS num
FROM mytable
GROUP BY col;

GROUP BY 自动按分组字段进行排序,ORDER BY 也可以按汇总字段来进行排序。上面这一行语句打印出来就是col,num的数对,每一个col对应一个统计数据。比如下面这个例子


SELECT col, COUNT(
) AS num
FROM mytable
GROUP BY col
ORDER BY num;
WHERE 过滤行,HAVING 过滤分组,行过滤应当先于分组过滤。

SELECT col, COUNT(*) AS num
FROM mytable
WHERE col > 2
GROUP BY col
HAVING num >= 2;
分组规定:
GROUP BY 子句出现在 WHERE 子句之后,ORDER BY 子句之前;
除了汇总字段外,SELECT 语句中的每一字段都必须在 GROUP BY 子句中给出;
NULL 的行会单独分为一组;
大多数 SQL 实现不支持 GROUP BY 列具有可变长度的数据类型。

子查询

子查询中只能返回一个字段的数据。
可以将子查询的结果作为 WHRER 语句的过滤条件:
SELECT *
FROM mytable1
WHERE col1 IN (SELECT col2
FROM mytable2);
下面的语句可以检索出客户的订单数量,子查询语句会对第一个查询检索出的每个客户执行一次:
SELECT cust_name, (SELECT COUNT(*)
FROM Orders
WHERE Orders.cust_id = Customers.cust_id)
AS orders_num
FROM Customers
ORDER BY cust_name;