SQL 教程

警告
本文最后更新于 2022-08-28,文中内容可能已过时。

结构化查询语言(Structured Query Language,SQL),读作S-Q-L或者sequel,是用来与数据库通信的语言。

SQL关键字不区分大小写。

  • 显示数据库
1
SHOW DATABASES;
  • 选择数据库
1
USE db_name;
  • 创建数据库
1
2
CREATE DATABASE db_name;
CREATE DATABASE IF NOT EXISTS db_name;
  • 删除数据库
1
DROP DATABASE db_name;
  • 显示创建数据库的 SQL 语句
1
SHOW CREATE DATABASE db_name;

  • 显示表
1
SHOW TABLES;
  • 描述表
1
2
DESCRIBE tb_name;
SHOW COLUMNS FROM tb_name;
  • 创建表
1
2
3
4
5
6
7
8
9
CREATE TABLE tb_name (
    col_1 type_1 cons_1,
    col_2 type_2 cons_2,
    cons_3,
    cons_4
);

-- 使用旧表创建新表
CREATE TABLE tb_new LIKE tb_old;
  • 显示创建表的 SQL 语句
1
SHOW CREATE TABLE tb_name;
  • 删除表
1
DROP TABLE tb_name;
  • 修改表名
1
ALTER TABLE tb_old RENAME TO tb_new;
  • 添加列
1
ALTER TABLE tb_name ADD COLUMN col_ type_ cons_;
  • 删除列
1
ALTER TABLE tb_name DROP COLUMN col_;
  • 修改列名
1
ALTER TABLE tb_name RENAME col_old TO col_new;
  • 添加约束
1
2
3
4
ALTER TABLE tb_name ADD cons;

-- 添加主键
ALTER TABLE tb_name ADD PRIMARY KEY (col_);
  • 删除约束
1
2
3
4
ALTER TABLE tb_name DROP cons;

-- 删除主键
ALTER TABLE tb_name DROP PRIMARY KEY (col_);
  • 创建索引
1
2
3
4
CREATE INDEX idx_name ON ta_name (col_1, col_2);

-- 唯一索引
CREATE UNIQUE INDEX idx_name ON ta_name (col_1, col_2);
  • 删除索引
1
DROP INDEX idx_name;

  • 添加
1
2
3
4
5
-- 添加多条记录
INSERT INTO tb_name (col_1, col_2) VALUES (val_1_1, val_1_2), (val_2_1, val_2_2);

-- 从其他表添加
INSERT INTO tb_name_1 (col_1, col_2) SELECT col_1, col_2 FROM tb_name_2;
  • 删除
1
2
3
4
5
6
-- 删除指定记录
DELETE FROM tb_name WHERE cond_;

-- 删除所有记录
DELETE FROM tb_name;
TRUNCATE TABLE tb_name;
  • 修改
1
UPDATE tb_name SET col_1=val_1, col_2=val_2 WHERE cond_;

  • 条件查询
1
2
3
4
5
-- 指定列
SELECT col_1, col_2 FROM tb_name WHERE cond_;

-- 所有列
SELECT * FROM tb_name;
  • 去重
1
SELECT DISTINCT col_ FROM tb_name;
  • 分页pos从 0 开始。
1
2
3
4
5
6
-- [0, len)
SELECT col_ FROM tb_name LIMIT len_;

-- [pos, pos + len)
SELECT col_ FROM tb_name LIMIT pos_, len_;
SELECT col_ FROM tb_name LIMIT len_ OFFSET pos_;
  • 排序
1
2
3
4
5
6
7
8
-- 升序,ASC
SELECT col_ FROM tb_name ORDER BY col_1;

-- 降序
SELECT col_ FROM tb_name ORDER BY col_1 DESC;

-- 复杂排序
SELECT col_ FROM tb_name ORDER BY col_1 DESC col_2 ASC;

1
2
3
4
5
6
7
8
-- 返回 tb_1 和 tb_2 的交集
SELECT col_ FROM tb_1 INNER JOIN tb_2 ON cond_;
-- 返回 tb_1 减去 tb_1 和 tb_2 的交集
SELECT col_ FROM tb_1 LEFT JOIN tb_2 ON cond_;
-- 返回 tb_2 减去 tb_1 和 tb_2 的交集
SELECT col_ FROM tb_1 RIGHT JOIN tb_2 ON cond_;
-- 返回 tb_1 和 tb_2 的笛卡尔积
SELECT col_ FROM tb_1 CROSS JOIN tb_2 ON cond_;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
select * from test1;
-- +------+------+
-- | r1   | r2   |
-- +------+------+
-- |    1 |    1 |
-- |    1 |    2 |
-- +------+------+
select * from test2;
-- +------+------+
-- | r1   | r2   |
-- +------+------+
-- |    1 |    2 |
-- |    2 |    2 |
-- +------+------+
select * from test1, test2;
-- +------+------+------+------+
-- | r1   | r2   | r1   | r2   |
-- +------+------+------+------+
-- |    1 |    2 |    1 |    2 |
-- |    1 |    1 |    1 |    2 |
-- |    1 |    2 |    2 |    2 |
-- |    1 |    1 |    2 |    2 |
-- +------+------+------+------+
select * from test1, test2 where test1.r1 = test2.r1;
-- +------+------+------+------+
-- | r1   | r2   | r1   | r2   |
-- +------+------+------+------+
-- |    1 |    2 |    1 |    2 |
-- |    1 |    1 |    1 |    2 |
-- +------+------+------+------+
select * from test1 inner join test2 on test1.r1 = test2.r1;
-- +------+------+------+------+
-- | r1   | r2   | r1   | r2   |
-- +------+------+------+------+
-- |    1 |    2 |    1 |    2 |
-- |    1 |    1 |    1 |    2 |
-- +------+------+------+------+

操作符说明
=等于
<>!=不等于
<小于
<=小于等于
>大于
>=大于等于
between <a> and <b>[a,b]
is null
逻辑操作符说明
and
or
not
in (<a>, <b>, <c>)等于abc
  • %表示任意字符任意次数(不能匹配NULL)
  • _表示单个任意字符
1
select <columns> from <table> where <column> like <pattern>;
  • \\两个反斜杠转义字符。
1
select <columns> from <table> where <column> regexp <pattern>;
字符类说明
[:alnum:]
[:alpha:]
[:blank:]
[:cntrl:]
[:digit:]
[:graph:]
[:lower:]
[:upper:]
[:print:]
[:punct:]
[:space:]
[:xdigit:]
  • 拼接:
1
select concat(<columns>) from <table>;
  • 计算:
1
select <column1> <op> <column2> as <alias> from <table>;
示例
1
2
3
4
5
6
7
8
9
-- demo
-- +------+----------+
-- | id   | name     |
-- +------+----------+
-- |    1 | zhangsan |
-- |    1 | lisi     |
-- |    2 | zhangsan |
-- |    2 | lisi     |
-- +------+----------+
1
2
3
4
5
6
7
8
9
select concat(id, ' ', name) as id_name from demo;
-- +------------+
-- | id_name    |
-- +------------+
-- | 1 zhangsan |
-- | 1 lisi     |
-- | 2 zhangsan |
-- | 2 lisi     |
-- +------------+
1
2
3
4
5
6
7
8
9
select id * 2 as id_double from demo;
-- +-----------+
-- | id_double |
-- +-----------+
-- |         2 |
-- |         2 |
-- |         4 |
-- |         4 |
-- +-----------+

流程控制:

  • CASE val WHEN val1 THEN res1 [WHEN val2 THEN res2 ...] [ELSE res] END:switch 语句,无匹配返回 NULL。
  • CASE WHEN cond1 THEN res1 [WHEN cond2 THEN res2 ...] [ELSE res] END:多重 if 语句,无匹配返回 NULL。
  • IF(expr1, expr2, expr3):若 expr1 为真返回 expr2 否则返回 expr3。
  • IFNULL(expr1, expr2):若 expr1 为 NULL,则返回 expr2,否则返回 expr1。
  • NULLIF(expr1, expr2):若 expr1 = expr2,返回 NULL,否则返回 expr1。

数值:

  • ROUND(x) | ROUND(x, d):四舍五入,保留 d 位小数,默认取整。
  • FLOOR(x):去尾法,取整。
  • CEILING(x):进一法,取整。同CEIL
  • FORMAT(x, d):保留 d 位小数,然后转为字符串。

统计量:

  • COUNT(expr) | COUNT(DISTINCT expr):行数(不包括 NULL),去重后行数(不包括 NULL)。
  • COUNT(*) | COUNT(1):行数(包括 NULL)。
  • SUM(col_name):求和。
  • AVG(col_name):平均值。
  • MAX(col_name):最大值。
  • MIN(col_name):最小值。

字符串:

  • LENGTH(str):返回 str 长度。
  • CHAR_LENGTH(str):返回非 ASCII 码字符串长度。比如’你好’返回 2。
  • LEFT(str, n):返回 str 长度为 n 的前缀子串。
  • RIGHT(str, n):返回 str 长度为 n 的后缀子串。
  • SUBSTRING(str, start):返回 str 从第 start 个字符开始直到末尾的子串。同SUBSTR
  • SUBSTRING(str, start, len):返回 str 从第 start 个字符开始长度为 len 的子串。同SUBSTR
  • CONCAT(s1, s2, ...):返回拼接后的字符串,不限制参数数量。
  • CONCAT_WS(c, s1, s2, ...):用分隔符 c 将字符串拼接起来。
  • LOWER(str):转为小写。
  • UPPER(str):转为大写。
  • TRIM(str):去掉两侧空白字符。
  • REVERSE(str):翻转字符串。

日期:

  • DATEDIFF(date1, date2):返回 date1 减去 date2 的天数。