《MySQL 查询语句入门到进阶》

《MySQL 查询语句入门到进阶》

本文从零梳理 MySQL 的 SELECT 查询语法,覆盖条件查询、模糊匹配、聚合分组、多表连接、分页、去重、视图等常用操作,以命令和示例为主,适合入门复习和速查。

1 主键与索引的区别

  1. 主键一定是唯一性索引,但唯一性索引并不一定就是主键。
  2. 一个表中可以有多个唯一索引,但只能有一个主键。
  3. 主键列不允许为空值,而唯一索引列允许为空值。
  4. 索引可以提高查询速度。
  5. 主键和索引都是键,但主键是逻辑键(用于标识记录),索引是物理键(实际存储在数据库中)。

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; -- 删除视图
阅读 — · 全站 —
🎸 我的歌单 0 首