【MySQL 笔记】基本查询(下)—— 表的增删改查 进阶 & 条件 / 排序 / 分页 / 聚合

上一期我们把最基础的 INSERT / UPDATE / DELETE / SELECT 语法过了一遍,今天继续把 SELECT 这个最核心的操作深入展开,重点放在:

  • WHERE 条件全家桶
  • 模糊查询 & 比较运算
  • 排序(ORDER BY)
  • 分页(LIMIT / OFFSET)
  • 简单聚合(COUNT / SUM / AVG / MAX / MIN)
  • 去重(DISTINCT)
  • 常用组合写法

这些内容几乎占了日常 SQL 开发的 70% 以上。

一、WHERE 条件常用运算符速查表

类别运算符示例说明 / 注意事项
比较=, !=, <>, >, <, >=, <=age > 18<> 和 != 等价,推荐用 <>
范围BETWEEN … AND …age BETWEEN 18 AND 35包含边界
集合IN / NOT INcity IN ('北京','上海','广州')比多个 OR 效率更高
空值IS NULL / IS NOT NULLdeleted_at IS NULL不能用 = NULL
布尔IS TRUE / IS FALSEis_active IS TRUEMySQL 中布尔是 tinyint(1)
模式匹配LIKE / NOT LIKEusername LIKE 'admin%'% 任意字符,_ 单个字符
正则REGEXP / NOT REGEXPemail REGEXP '^[a-z0-9._%+-]+@'性能较差,慎用在大数据量
逻辑AND / OR / NOTstatus = 'active' AND age >= 18AND 优先级高于 OR,建议加括号

二、模糊查询(LIKE)最常见写法

-- 前缀匹配(最常用,索引友好)
WHERE username LIKE 'zhangsan%'          -- zhangsan 开头的都匹配

-- 后缀匹配(索引通常失效)
WHERE email LIKE '%@163.com'

-- 任意位置包含(索引基本失效)
WHERE nickname LIKE '%铁锤%'

-- 精确长度匹配(_ 表示一个字符)
WHERE phone LIKE '138________'           -- 138 开头的11位手机号

-- 组合模糊 + 条件
WHERE (username LIKE 'admin%' OR nickname LIKE '%admin%')
  AND status = 'active'

三、排序(ORDER BY) & 分页(LIMIT)

-- 1. 单字段排序
SELECT * FROM products 
ORDER BY price DESC;                -- 降序

-- 2. 多字段排序(先按销量降序,销量相同再按价格升序)
SELECT * FROM products 
ORDER BY sales DESC, price ASC;

-- 3. 按计算结果排序
SELECT id, username, login_count + 1 AS new_count
FROM users 
ORDER BY new_count DESC;

-- 4. 常见分页写法(第 n 页,每页 size 条)
-- 第1页
SELECT * FROM orders 
ORDER BY created_at DESC 
LIMIT 10;

-- 第3页(每页20条)
SELECT * FROM orders 
ORDER BY created_at DESC 
LIMIT 20 OFFSET 40;          -- 跳过前40条

-- 推荐写法(更清晰)
LIMIT (page-1)*size, size

四、简单聚合函数(无 GROUP BY 时)

函数作用示例返回类型 / 注意
COUNT()统计行数COUNT(*) / COUNT(id)COUNT(*) 包含 NULL,COUNT(列) 不含
SUM()求和SUM(amount)只对数值有效
AVG()平均值AVG(score)忽略 NULL
MAX()最大值MAX(created_at)日期、字符串、数字都支持
MIN()最小值MIN(price)同上
-- 统计活跃用户数
SELECT COUNT(*) AS active_users 
FROM users 
WHERE status = 'active' AND deleted_at IS NULL;

-- 今日订单总额 &amp; 平均订单金额
SELECT 
    COUNT(*) AS order_count,
    ROUND(SUM(amount), 2) AS total_amount,
    ROUND(AVG(amount), 2) AS avg_amount,
    MAX(amount) AS max_order,
    MIN(amount) AS min_order
FROM orders 
WHERE DATE(created_at) = CURDATE();

五、去重(DISTINCT) & 组合查询示例

-- 1. 查询注册过的城市(去重)
SELECT DISTINCT city 
FROM users 
WHERE city IS NOT NULL 
ORDER BY city;

-- 2. 组合条件 + 排序 + 分页 + 限制字段
SELECT id, username, nickname, last_login_time
FROM users
WHERE status = 'active'
  AND last_login_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
  AND nickname LIKE '%李%'
ORDER BY last_login_time DESC
LIMIT 15 OFFSET 0;

-- 3. 统计每个状态的用户数量(引入 GROUP BY 预告)
SELECT status, COUNT(*) AS user_count
FROM users
WHERE deleted_at IS NULL
GROUP BY status
ORDER BY user_count DESC;

六、写 SELECT 的高频安全 & 性能建议(2026 年视角)

  1. 永远不要在生产直接 SELECT *
  • 列出明确需要的字段
  • 减少 IO、网络传输、内存占用
  1. WHERE 条件顺序建议(虽然优化器会调整,但可读性重要)
  • 先写最能过滤的条件(区分度高的)
  • 再写范围 / LIKE
  • 最后写 OR / 函数条件
  1. LIKE 前缀匹配 才能用索引
  • LIKE 'abc%' → 好
  • LIKE '%abc' → 差
  1. 分页大数据量 推荐“延迟关联”或“游标分页”
   -- 传统方式(越往后越慢)
   SELECT * FROM logs ORDER BY id DESC LIMIT 1000000,10;

   -- 推荐:先找 id 再查详情
   SELECT * FROM logs 
   WHERE id &lt;= (SELECT id FROM logs ORDER BY id DESC LIMIT 1000000,1)
   ORDER BY id DESC 
   LIMIT 10;
  1. COUNT() vs COUNT(1) vs COUNT(主键)
    → MySQL 优化后几乎无差别,COUNT(
    ) 最直观

下一期预告:MySQL 聚合查询 & GROUP BY & HAVING & WITH ROLLUP 详解

有哪种条件组合 / 分页场景你觉得写起来特别烦,或者项目里最常见的 SELECT 模板,欢迎留言,我们一起整理~
祝大家 SELECT 写得精准又高效!🔍

【MySQL 笔记】基本查询(下)—— 表的增删改查 进阶 & 条件 / 排序 / 分页 / 聚合

上一期我们把最基础的 INSERT / UPDATE / DELETE / SELECT 语法过了一遍,今天继续把 SELECT 这个最核心的操作深入展开,重点放在:

  • WHERE 条件全家桶
  • 模糊查询 & 比较运算
  • 排序(ORDER BY)
  • 分页(LIMIT / OFFSET)
  • 简单聚合(COUNT / SUM / AVG / MAX / MIN)
  • 去重(DISTINCT)
  • 常用组合写法

这些内容几乎占了日常 SQL 开发的 70% 以上。

一、WHERE 条件常用运算符速查表

类别运算符示例说明 / 注意事项
比较=, !=, <>, >, <, >=, <=age > 18<> 和 != 等价,推荐用 <>
范围BETWEEN … AND …age BETWEEN 18 AND 35包含边界
集合IN / NOT INcity IN ('北京','上海','广州')比多个 OR 效率更高
空值IS NULL / IS NOT NULLdeleted_at IS NULL不能用 = NULL
布尔IS TRUE / IS FALSEis_active IS TRUEMySQL 中布尔是 tinyint(1)
模式匹配LIKE / NOT LIKEusername LIKE 'admin%'% 任意字符,_ 单个字符
正则REGEXP / NOT REGEXPemail REGEXP '^[a-z0-9._%+-]+@'性能较差,慎用在大数据量
逻辑AND / OR / NOTstatus = 'active' AND age >= 18AND 优先级高于 OR,建议加括号

二、模糊查询(LIKE)最常见写法

-- 前缀匹配(最常用,索引友好)
WHERE username LIKE 'zhangsan%'          -- zhangsan 开头的都匹配

-- 后缀匹配(索引通常失效)
WHERE email LIKE '%@163.com'

-- 任意位置包含(索引基本失效)
WHERE nickname LIKE '%铁锤%'

-- 精确长度匹配(_ 表示一个字符)
WHERE phone LIKE '138________'           -- 138 开头的11位手机号

-- 组合模糊 + 条件
WHERE (username LIKE 'admin%' OR nickname LIKE '%admin%')
  AND status = 'active'

三、排序(ORDER BY) & 分页(LIMIT)

-- 1. 单字段排序
SELECT * FROM products 
ORDER BY price DESC;                -- 降序

-- 2. 多字段排序(先按销量降序,销量相同再按价格升序)
SELECT * FROM products 
ORDER BY sales DESC, price ASC;

-- 3. 按计算结果排序
SELECT id, username, login_count + 1 AS new_count
FROM users 
ORDER BY new_count DESC;

-- 4. 常见分页写法(第 n 页,每页 size 条)
-- 第1页
SELECT * FROM orders 
ORDER BY created_at DESC 
LIMIT 10;

-- 第3页(每页20条)
SELECT * FROM orders 
ORDER BY created_at DESC 
LIMIT 20 OFFSET 40;          -- 跳过前40条

-- 推荐写法(更清晰)
LIMIT (page-1)*size, size

四、简单聚合函数(无 GROUP BY 时)

函数作用示例返回类型 / 注意
COUNT()统计行数COUNT(*) / COUNT(id)COUNT(*) 包含 NULL,COUNT(列) 不含
SUM()求和SUM(amount)只对数值有效
AVG()平均值AVG(score)忽略 NULL
MAX()最大值MAX(created_at)日期、字符串、数字都支持
MIN()最小值MIN(price)同上
-- 统计活跃用户数
SELECT COUNT(*) AS active_users 
FROM users 
WHERE status = 'active' AND deleted_at IS NULL;

-- 今日订单总额 &amp; 平均订单金额
SELECT 
    COUNT(*) AS order_count,
    ROUND(SUM(amount), 2) AS total_amount,
    ROUND(AVG(amount), 2) AS avg_amount,
    MAX(amount) AS max_order,
    MIN(amount) AS min_order
FROM orders 
WHERE DATE(created_at) = CURDATE();

五、去重(DISTINCT) & 组合查询示例

-- 1. 查询注册过的城市(去重)
SELECT DISTINCT city 
FROM users 
WHERE city IS NOT NULL 
ORDER BY city;

-- 2. 组合条件 + 排序 + 分页 + 限制字段
SELECT id, username, nickname, last_login_time
FROM users
WHERE status = 'active'
  AND last_login_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
  AND nickname LIKE '%李%'
ORDER BY last_login_time DESC
LIMIT 15 OFFSET 0;

-- 3. 统计每个状态的用户数量(引入 GROUP BY 预告)
SELECT status, COUNT(*) AS user_count
FROM users
WHERE deleted_at IS NULL
GROUP BY status
ORDER BY user_count DESC;

六、写 SELECT 的高频安全 & 性能建议(2026 年视角)

  1. 永远不要在生产直接 SELECT *
  • 列出明确需要的字段
  • 减少 IO、网络传输、内存占用
  1. WHERE 条件顺序建议(虽然优化器会调整,但可读性重要)
  • 先写最能过滤的条件(区分度高的)
  • 再写范围 / LIKE
  • 最后写 OR / 函数条件
  1. LIKE 前缀匹配 才能用索引
  • LIKE 'abc%' → 好
  • LIKE '%abc' → 差
  1. 分页大数据量 推荐“延迟关联”或“游标分页”
   -- 传统方式(越往后越慢)
   SELECT * FROM logs ORDER BY id DESC LIMIT 1000000,10;

   -- 推荐:先找 id 再查详情
   SELECT * FROM logs 
   WHERE id &lt;= (SELECT id FROM logs ORDER BY id DESC LIMIT 1000000,1)
   ORDER BY id DESC 
   LIMIT 10;
  1. COUNT() vs COUNT(1) vs COUNT(主键)
    → MySQL 优化后几乎无差别,COUNT(
    ) 最直观

下一期预告:MySQL 聚合查询 & GROUP BY & HAVING & WITH ROLLUP 详解

有哪种条件组合 / 分页场景你觉得写起来特别烦,或者项目里最常见的 SELECT 模板,欢迎留言,我们一起整理~
祝大家 SELECT 写得精准又高效!🔍

文章已创建 5186

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部