《MySQL 查询语句入门到进阶》
本文从零梳理 MySQL 的 SELECT 查询语法,覆盖条件查询、模糊匹配、聚合分组、多表连接、分页、去重、视图等常用操作,以命令和示例为主,适合入门复习和速查。
1 主键与索引的区别
- 主键一定是唯一性索引,但唯一性索引并不一定就是主键。
- 一个表中可以有多个唯一索引,但只能有一个主键。
- 主键列不允许为空值,而唯一索引列允许为空值。
- 索引可以提高查询速度。
- 主键和索引都是键,但主键是逻辑键(用于标识记录),索引是物理键(实际存储在数据库中)。
2 SELECT 基础查询
2.1 查询全部字段
SELECT * FROM table_name;
SELECT:查询关键字。*:通配符,表示查询表中所有字段。FROM:表示从哪个表查询。
2.2 查询指定字段
SELECT name, age FROM table_name;
要查询哪个字段,就把字段名写在 SELECT 与 FROM 之间,多个字段用逗号分隔。
2.3 条件查询
SELECT * FROM table_name WHERE age = 20;
WHERE之后的内容都称为条件。- 字符串类型的字段值必须使用单引号包裹,数字类型可加也可不加。
2.4 按逻辑运算符筛选
SELECT * FROM table_name WHERE age <> 50;
SELECT * FROM table_name WHERE age > 20 AND age < 50;
支持 =、!=、<、>、<=、>=、<>(表示不等于)。
2.5 多条件查询 AND / OR
SELECT * FROM table_name WHERE age < 50 AND salary > 8000 AND leader = 0;
SELECT * FROM table_name WHERE age < 40 OR (salary < 8000 AND leader != '0');
AND:逻辑与,多个条件必须同时成立。OR:逻辑或,满足其中一个条件即可。- 括号表示一组条件,优先级最高。
2 DISTINCT 去重查询
SELECT DISTINCT state, city FROM customers
WHERE state IS NOT NULL
ORDER BY state, city;
DISTINCT对查询结果去重,一般只对单一字段使用效果最好。- 多字段去重时,DISTINCT 会作用于所有列出字段的组合。
- 用
GROUP BY同样可以实现去重:
SELECT menpai, name FROM table_name GROUP BY menpai;
3 模糊查询 LIKE
SELECT * FROM table_name WHERE name LIKE '%张%';
- 以「张」开头:
LIKE '张%' - 以「张」结尾:
LIKE '%张' - 包含「张」:
LIKE '%张%'
4 集合查询 IN / NOT IN
SELECT * FROM table_name WHERE menpai IN ('武当', '明教', '嵩山');
SELECT * FROM table_name WHERE menpai NOT IN ('武当', '明教', '嵩山');
IN 等价于多个 OR 条件;集合使用括号包裹。
5 区间查询 BETWEEN
SELECT * FROM table_name WHERE salary BETWEEN 4000 AND 8000;
等价于 salary >= 4000 AND salary <= 8000。
6 排序 ORDER BY
SELECT * FROM table_name ORDER BY salary ASC; -- 正序
SELECT * FROM table_name ORDER BY salary DESC; -- 倒序
7 子查询
SELECT * FROM table_name
WHERE leader IN (SELECT p_id FROM table_name WHERE age = 20);
WHERE后面的条件本身可以是一个查询结果。- 子查询返回单一值时可用
=,返回多行时必须用IN。 - 判断原则:遇到
=是单值,遇到IN是集合。
8 聚合函数
SELECT MAX(salary) AS salary FROM table_name; -- 最大值
SELECT MIN(salary) AS salary FROM table_name; -- 最小值
SELECT AVG(salary) AS salary FROM table_name; -- 平均值
SELECT SUM(salary) AS salary FROM table_name; -- 求和
SELECT COUNT(*) AS total FROM table_name; -- 总条数
AS 用于为字段或结果集起别名。
9 分组查询 GROUP BY
SELECT menpai, AVG(salary) FROM table_name GROUP BY menpai;
GROUP BY按指定字段分组,一般与聚合函数一起使用。
9.1 分组后过滤 HAVING
SELECT menpai, MAX(salary) FROM table_name
GROUP BY menpai
HAVING menpai = 'column';
HAVING用于给分组或聚合结果加条件,只与GROUP BY一起使用。- 分组后不加条件时,
HAVING可以省略。
9.2 使用结果集作为表
SELECT MAX(salary) FROM (
SELECT salary FROM table_name WHERE menpai = 'column'
) AS tmp_table;
注意:结果集作为表时必须起别名,否则会报错。
10 分页查询 LIMIT
SELECT * FROM table_name LIMIT 4, 8;
- 参数 1:从第几条数据开始查询(偏移量,从 0 开始)。
- 参数 2:每页返回条数。
LIMIT offset, count是经典的分页写法。
11 连接查询 JOIN
11.1 多表联合查询(笛卡尔积)
SELECT * FROM table_name r, another_table w
WHERE r.menpai = w.a_name;
- 多表联合(逗号连接)的结果是两张表的笛卡尔积,必须用
WHERE条件过滤。
11.2 左连接 LEFT JOIN
SELECT * FROM table_name r
LEFT JOIN another_table w ON r.menpai = w.a_name;
- 以左表为准,左表数据全要,右表没有匹配数据时用 NULL 填充。
11.3 右连接 RIGHT JOIN
SELECT * FROM table_name r
RIGHT JOIN another_table w ON w.a_name = r.menpai;
- 以右表为准,右表数据全要,左表没有匹配的用 NULL 填充。
11.4 内连接 INNER JOIN
SELECT * FROM table_name r
INNER JOIN another_table w ON w.a_name = r.menpai;
- 只返回两边都匹配的数据,结果等同于加过滤条件的多表联合查询。
11.5 合并结果 UNION
SELECT r.menpai, r.name FROM table_name r
UNION
SELECT w.a_name, w.a_name FROM another_table w;
UNION合并两个或以上 SELECT 的结果集,并自动去重;如需保留全部重复行用UNION ALL。
12 NULL 查询
SELECT * FROM table_name WHERE name IS NULL; -- 查询 NULL 值
SELECT * FROM table_name WHERE name IS NOT NULL; -- 查询非 NULL 值
SELECT * FROM table_name WHERE name = ''; -- 查询空字符串
注意:NULL 值不能使用 = 判断,只能使用 IS NULL / IS NOT NULL。
13 数据增删改
-- 新增:字段与值一一对应
INSERT INTO wei(a_id, a_name, a_address) VALUES ('a006', '安全', '浙江');
-- 修改:set 关键字只会出现一次
UPDATE wei SET a_name = '新的', a_address = '江苏' WHERE a_id = 'a007';
-- 删除:务必带上主键条件,防止误删全表
DELETE FROM wei WHERE a_id = 'a007';
14 建表与索引
CREATE TABLE table_name (
p_id varchar(50) NOT NULL,
name varchar(255) DEFAULT NULL,
age int(10) DEFAULT 0,
menpai varchar(255) DEFAULT NULL,
leader varchar(50) DEFAULT NULL,
salary int(10) DEFAULT 0,
PRIMARY KEY (p_id),
UNIQUE KEY name_key (name, menpai),
KEY psal (salary)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
PRIMARY KEY:主键。UNIQUE KEY 索引名(字段...):唯一索引。KEY 索引名(字段...):普通索引。- 索引好处:提高查询效率,数据量越大效果越明显;缺点:增删数据时索引维护会导致效率下降。
14.1 单独添加索引
CREATE INDEX idx_name ON table_name(name); -- 普通索引
CREATE UNIQUE INDEX idx_age ON table_name(age); -- 唯一索引
14.2 删除
DROP TABLE IF EXISTS table_name; -- 若表存在则删除,避免报错
15 视图
视图可以理解为一张临时表(实际为已保存的 SQL),用于简化复杂查询。
CREATE VIEW ren_view AS SELECT p_id, name, age, leader FROM table_name;
SELECT * FROM v_person; -- 查询视图
UPDATE v_person SET age = 99 WHERE p_id = 'p004'; -- 修改视图数据
DELETE FROM v_person WHERE p_id = 'p010'; -- 删除视图数据
DROP VIEW v_person; -- 删除视图
阅读 —
·
全站 —