news 2026/5/13 10:17:37

SQL--

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL--

FROM → JOIN → ON → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT

  • 表连条件 → FROM / JOIN / ON

  • 行筛 → WHERE

  • 分组 → GROUP BY

  • 筛组 → HAVING

  • 选列去重 → SELECT / DISTINCT

  • 排好序 → ORDER BY

  • 截断定长度 → LIMIT / OFFSET

=========================================
SQL 聚合函数与高级关键字完整版总结
=========================================

一、聚合函数(Aggregate Functions)
------------------------------------

1. COUNT()

作用:
统计行数。

写法区别:

1)COUNT(*)
统计总行数(包括NULL)
推荐使用。

2)COUNT(1)
效果等同 COUNT(*)。

3)COUNT(字段)
统计该字段不为 NULL 的行数。

示例:
SELECT COUNT(*) FROM user;
SELECT COUNT(age) FROM user;

注意:
COUNT(字段) 会忽略 NULL。


2. SUM()

作用:
对数值字段求总和。

示例:
SELECT SUM(amount) FROM orders;

特点:
- 忽略 NULL
- 如果全部是 NULL,返回 NULL

安全写法:
SELECT IFNULL(SUM(amount),0) FROM orders;


3. AVG()

作用:
求平均值。

示例:
SELECT AVG(score) FROM student;

特点:
- 忽略 NULL
- 实际等于 SUM / COUNT(非NULL)


4. MAX()

作用:
获取最大值。

示例:
SELECT MAX(age) FROM user;

特点:
- 忽略 NULL
- 可用于字符串


5. MIN()

作用:
获取最小值。

示例:
SELECT MIN(age) FROM user;

特点:
- 忽略 NULL
- 可用于字符串


====================================
二、EXISTS
====================================

作用:
判断子查询是否存在结果。

语法:

SELECT *
FROM user u
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.user_id = u.id
);

特点:
- 只要子查询返回一条记录即为 TRUE
- 存在即停止(短路机制)
- 通常适用于大表


====================================
三、ANY
====================================

作用:
满足子查询结果中的任意一个条件。

示例:

SELECT *
FROM product
WHERE price > ANY (
SELECT price FROM product WHERE category_id = 1
);

等价理解:
> ANY 等价于 > MIN
< ANY 等价于 < MAX


====================================
四、ALL
====================================

作用:
必须满足子查询结果中的所有条件。

示例:

SELECT *
FROM product
WHERE price > ALL (
SELECT price FROM product WHERE category_id = 1
);

等价理解:
> ALL 等价于 > MAX
< ALL 等价于 < MIN


====================================
五、UNION
====================================

作用:
合并多个查询结果,并自动去重。

示例:

SELECT name FROM student
UNION
SELECT name FROM teacher;

特点:
- 自动去重
- 列数必须一致
- 数据类型必须兼容
- 性能比 UNION ALL 低


====================================
六、UNION ALL
====================================

作用:
合并多个查询结果,不去重。

示例:

SELECT name FROM student
UNION ALL
SELECT name FROM teacher;

特点:
- 不去重
- 性能更高
- 推荐优先使用(如果不需要去重)


====================================
七、CASE WHEN THEN ELSE END
====================================

作用:
条件表达式(类似 if-else)。

语法:

SELECT
name,
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS level
FROM student;

执行顺序:
- 从上到下判断
- 第一个满足条件即返回
- 然后停止


等值写法:

CASE gender
WHEN 'M' THEN '男'
WHEN 'F' THEN '女'
END


条件统计写法:

SELECT
SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS total_paid
FROM orders;


====================================
八、AS —— 起别名
====================================

1)字段别名

SELECT name AS username FROM user;

AS 可以省略:

SELECT name username FROM user;


2)表别名

SELECT u.name
FROM user AS u;


3)子查询必须起别名

SELECT *
FROM (
SELECT user_id, COUNT(*) c
FROM orders
GROUP BY user_id
) AS t;


====================================
九、LEFT JOIN
====================================

作用:
左连接,返回左表所有数据,
右表没有匹配则返回 NULL。

语法:

SELECT *
FROM user u
LEFT JOIN orders o
ON u.id = o.user_id;

特点:
- 左表数据一定全部返回
- 右表无匹配则为 NULL
- 常用于查“有无”关系

示例:查询没有订单的用户

SELECT u.*
FROM user u
LEFT JOIN orders o
ON u.id = o.user_id
WHERE o.id IS NULL;

注意:
- 连接条件必须写在 ON 中
- 过滤右表字段放在 WHERE 会改变结果


====================================
十、GROUP BY 注意事项(重要)
====================================

规则:
SELECT 中出现的字段:

1)要么是聚合函数
2)要么必须出现在 GROUP BY 中

错误写法:

SELECT user_id, amount
FROM orders
GROUP BY user_id;

原因:
amount 既不是聚合函数,也不在 GROUP BY 中。

正确写法:

SELECT user_id, SUM(amount)
FROM orders
GROUP BY user_id;

或者:

SELECT user_id, amount
FROM orders
GROUP BY user_id, amount;

说明:
- 标准SQL必须严格遵守
- MySQL某些模式下允许,但不规范
- 面试中必须回答为错误


====================================
总结
====================================

聚合函数:
COUNT
SUM
AVG
MAX
MIN

子查询判断:
EXISTS
ANY
ALL

结果合并:
UNION
UNION ALL

条件表达式:
CASE
WHEN
THEN
ELSE
END

连接:
LEFT JOIN

分组规则:
GROUP BY 中不能出现非聚合字段

别名:
AS

====================================

====================================
MySQL 常用日期函数总结
====================================

一、获取当前时间
------------------------------------

1. NOW()
返回当前日期 + 时间(年月日 时分秒)

示例:
SELECT NOW();

返回示例:
2026-02-21 15:30:00


2. CURDATE()
返回当前日期(只有年月日)

示例:
SELECT CURDATE();

返回示例:
2026-02-21


3. CURTIME()
返回当前时间(只有时分秒)

示例:
SELECT CURTIME();

返回示例:
15:30:00


====================================
二、提取日期部分
====================================

1. YEAR(date)
提取年份

2. MONTH(date)
提取月份

3. DAY(date)
提取日期

4. HOUR(datetime)
提取小时

5. MINUTE(datetime)
提取分钟

6. SECOND(datetime)
提取秒

示例:
SELECT YEAR(create_time) FROM orders;
SELECT MONTH(create_time) FROM orders;


====================================
三、日期加减
====================================

1. DATE_ADD(date, INTERVAL 数值 单位)
日期增加

示例:
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY);

2. DATE_SUB(date, INTERVAL 数值 单位)
日期减少

示例:
SELECT DATE_SUB(NOW(), INTERVAL 7 DAY);

常用单位:

SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
YEAR


====================================
四、日期差值计算
====================================

1. DATEDIFF(date1, date2)
返回两个日期之间相差的天数
忽略时分秒

示例:
SELECT DATEDIFF('2026-02-21', '2026-02-18');
结果:3


2. TIMESTAMPDIFF(单位, start, end)
可指定单位计算差值

示例:
SELECT TIMESTAMPDIFF(DAY, start_time, end_time);
SELECT TIMESTAMPDIFF(HOUR, start_time, end_time);

常用单位:

SECOND
MINUTE
HOUR
DAY
MONTH
YEAR


====================================
五、日期格式化
====================================

1. DATE_FORMAT(date, 格式)

示例:
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d');

常用格式符:

%Y 四位年份
%y 两位年份
%m 月份
%d 日期
%H 小时(24小时制)
%i 分钟
%s 秒


====================================
六、字符串转日期
====================================

1. STR_TO_DATE(str, 格式)

示例:
SELECT STR_TO_DATE('2026-02-21', '%Y-%m-%d');


====================================
七、时间戳相关
====================================

1. UNIX_TIMESTAMP()
返回时间戳

示例:
SELECT UNIX_TIMESTAMP(NOW());

2. FROM_UNIXTIME(timestamp)
时间戳转日期

示例:
SELECT FROM_UNIXTIME(1708500000);


====================================
八、企业推荐写法(重要)
====================================

查询今天数据(DATETIME 字段):

正确写法(推荐):

WHERE create_time >= CURDATE()
AND create_time < DATE_ADD(CURDATE(), INTERVAL 1 DAY);

不推荐写法(会导致索引失效):

WHERE DATE(create_time) = CURDATE();


查询最近7天:

WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY);


====================================
九、最常用函数(必须掌握)
====================================

NOW()
CURDATE()
DATE_ADD()
DATE_SUB()
DATEDIFF()
TIMESTAMPDIFF()
DATE_FORMAT()

====================================

====================================
MySQL WITH(CTE)用法总结
====================================

一、什么是 WITH

WITH 是公共表表达式(Common Table Expression,简称 CTE)。

作用:
给一个子查询起名字,使 SQL 更清晰、可读性更强。


基本语法:

WITH 表名 AS (
子查询
)
SELECT * FROM 表名;


====================================
二、基本示例
====================================

WITH tmp AS (
SELECT uid, COUNT(*) AS cnt
FROM tb_user_video_log
GROUP BY uid
)
SELECT *
FROM tmp;


说明:
tmp 是一个临时结果集,
仅在当前 SQL 语句中有效。


====================================
三、多个 WITH
====================================

WITH t1 AS (
SELECT ...
),
t2 AS (
SELECT ...
)
SELECT *
FROM t1
JOIN t2 ON ...;


多个 CTE 用逗号分隔。


====================================
四、使用场景
====================================

1)复杂查询分步骤写
2)替代嵌套子查询
3)滑动窗口计算
4)数据预处理
5)分层统计


====================================
五、滑动窗口示例(常见面试题)
====================================

WITH daily_stat AS (
SELECT
v.tag,
DATE(l.start_time) AS dt,
SUM(l.if_like) AS like_cnt,
SUM(l.if_retweet) AS retweet_cnt
FROM tb_user_video_log l
JOIN tb_video_info v
ON l.video_id = v.video_id
GROUP BY v.tag, DATE(l.start_time)
)

SELECT
a.tag,
a.dt,
SUM(b.like_cnt) AS week_like_cnt,
MAX(b.retweet_cnt) AS week_max_retweet
FROM daily_stat a
JOIN daily_stat b
ON a.tag = b.tag
AND b.dt BETWEEN DATE_SUB(a.dt, INTERVAL 6 DAY) AND a.dt
GROUP BY a.tag, a.dt;


====================================
六、WITH 和子查询区别
====================================

普通子查询:

SELECT *
FROM (
SELECT ...
) t;


WITH 写法:

WITH t AS (
SELECT ...
)
SELECT *
FROM t;


区别:

1)WITH 可读性更强
2)复杂逻辑更清晰
3)可以定义多个临时结果集


====================================
七、递归 WITH(高级)
====================================

WITH RECURSIVE t AS (
初始查询
UNION ALL
递归查询
)
SELECT * FROM t;


常用于:

1)树结构查询
2)层级数据
3)连续日期生成


====================================
八、注意事项
====================================

1)MySQL 8.0 以上才支持 WITH
2)CTE 只在当前语句中有效
3)性能上通常等同于子查询
4)CTE 必须写在最前面


====================================
九、总结
====================================

WITH = 给子查询起名字

优势:
- 结构清晰
- 可读性强
- 适合复杂统计
- 面试高频考点

====================================

MySQL 窗口函数介绍

窗口函数是在不改变行数的情况下,对一组行计算聚合、排名或累积等指标。它和普通聚合函数的区别如下:

聚合函数行数变化示例
SUM()会合并行数SELECT artical_id, SUM(delta) FROM events GROUP BY artical_id
SUM() OVER()不合并行数每一行都有“当前累计值”,保留原始行

基本语法:

聚合函数/排名函数() OVER (
[PARTITION BY 分组字段]
[ORDER BY 排序字段 [ASC|DESC]]
[窗口帧定义]
)

窗口函数使用规则:

  1. 每个窗口函数必须使用 OVER() 语法。

  2. 可以使用 PARTITION BY 分组,但不合并行,只是独立计算。

  3. ORDER BY 定义累积或排名顺序,顺序对结果有直接影响。

  4. 窗口帧可选,用于定义累积范围,如 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW。

  5. 同一行可以同时使用多个窗口函数。

  6. 窗口函数不能用于 WHERE 子句,但可用于 SELECT、ORDER BY、HAVING 等。

窗口帧使用及场景:

  1. ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

    • 当前行 = 窗口函数正在计算的这一行

    • 含义:从分组第一行累加到当前行

    • 返回值:窗口范围内的累积值

    • 场景:累计销售额、文章最大同时在线人数

  2. ROWS BETWEEN N PRECEDING AND CURRENT ROW

    • 含义:当前行及之前 N 行

    • 返回值:最近 N+1 行的聚合值

    • 场景:滑动平均值、最近 N 条记录总和

  3. ROWS BETWEEN CURRENT ROW AND N FOLLOWING

    • 含义:当前行及之后 N 行

    • 返回值:当前行及未来 N 行的聚合值

    • 场景:预测未来 N 条数据累计值

  4. ROWS BETWEEN N PRECEDING AND M FOLLOWING

    • 含义:当前行前 N 行 + 当前行 + 当前行后 M 行

    • 返回值:前后 N+M+1 行的聚合值

    • 场景:前后各几条记录平均值或总和

示例 1:文章最大同时在线人数
表 events:

uidartical_iddeltaevent_time
1019001110:00:00
1029001110:00:05
1039001110:00:10
1019001-110:00:11

SQL:
SELECT event_time, delta, SUM(delta) OVER(PARTITION BY artical_id ORDER BY event_time, delta DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS current_uv FROM events;

输出:

event_timedeltacurrent_uv
10:00:0011
10:00:0512
10:00:1013
10:00:11-12

示例 2:滑动平均
SQL:
SELECT sale_id, sale_date, amount, AVG(amount) OVER(ORDER BY sale_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg FROM sales;

常用窗口函数类型:

类型函数示例作用
聚合类SUM() OVER(), AVG() OVER()累积、滑动平均
排名类ROW_NUMBER() OVER(), RANK() OVER(), DENSE_RANK() OVER()排名、排序
值类LEAD(), LAG()获取前一行/后一行的值

总结:

  • 窗口函数对每一行返回一个值,该值根据窗口帧定义计算

  • current row = 窗口函数正在处理的那一行

  • ROWS 类型窗口帧适合累积和滑动统计,RANGE 类型适合按值范围累加

  • 使用 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 可以保证累积值精确且顺序正确

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/13 10:17:30

Degrees of Lewdity游戏汉化安装完全指南

Degrees of Lewdity游戏汉化安装完全指南 为解决英文游戏界面带来的体验障碍&#xff0c;本文提供一套系统的Degrees of Lewdity游戏汉化安装方案。通过环境预检、核心流程操作、效果验证及升级维护四个阶段&#xff0c;帮助用户实现游戏的完整中文化&#xff0c;适用于Window…

作者头像 李华
网站建设 2026/5/13 10:17:20

如何构建开源项目全球化适配:多语言架构设计与实战指南

如何构建开源项目全球化适配&#xff1a;多语言架构设计与实战指南 在全球化协作时代&#xff0c;开源项目的多语言支持已从"加分项"变为"必备能力"。数据显示&#xff0c;支持本地语言的开源项目可提升65%的国际用户参与度&#xff0c;同时降低新用户的入…

作者头像 李华
网站建设 2026/5/13 10:16:26

真香福利!AtomGit 正式推出CodingPlan:限时免费领取GLM5.1

过去一年&#xff0c;AI 编程的变化很快。模型越来越强&#xff0c;代码生成越来越顺&#xff0c;问题也变得越来越现实&#xff1a;不是“能不能写代码”&#xff0c;而是“能不能稳定地写代码”。很多开发者都有过类似体验&#xff1a;今天用得很顺&#xff0c;明天突然限流&…

作者头像 李华
网站建设 2026/5/13 10:15:32

Android Studio中文界面配置终极指南:3分钟搞定中文插件安装

Android Studio中文界面配置终极指南&#xff1a;3分钟搞定中文插件安装 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本&#xff09; 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 还在为An…

作者头像 李华
网站建设 2026/5/13 10:14:21

Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day7 最终闭环篇|真机全流程演示+毕设答辩总结+源码梳理+扩展方向+项目交付(**补全可运行代码版**)

Flutter 开源鸿蒙实战&#xff5c;城市智慧停车管理系统 Day7 最终闭环篇&#xff5c;真机全流程演示毕设答辩总结源码梳理扩展方向项目交付&#xff08;补全可运行代码版&#xff09; 欢迎加入开源鸿蒙跨平台社区&#xff1a;https://openharmonycrossplatform.csdn.net <…

作者头像 李华
网站建设 2026/5/13 10:13:58

Linux下CH341SER驱动终极指南:轻松解决Arduino串口连接问题

Linux下CH341SER驱动终极指南&#xff1a;轻松解决Arduino串口连接问题 【免费下载链接】CH341SER CH341SER driver with fixed bug 项目地址: https://gitcode.com/gh_mirrors/ch/CH341SER 你是否曾经在Linux系统中尝试连接Arduino开发板&#xff0c;却发现设备无法识别…

作者头像 李华