MySQL 内置函数 + 内外连接 超实用总结(2026 面试+生产必备)
一、MySQL 最常用内置函数(背会这 50 个,够用 99% 场景)
1. 字符串函数(最常用 TOP10)
| 函数 | 说明 | 示例 | 结果 |
|---|---|---|---|
| CONCAT(str1,str2,…) | 拼接字符串(NULL 会污染) | CONCAT(‘A’,’B’,NULL) | NULL |
| CONCAT_WS(sep,str1,str2..) | 带分隔符拼接(NULL 不影响) | CONCAT_WS(‘-‘,’A’,’B’,NULL,’C’) | A-B-C |
| LEFT(str,len) | 左起 len 个字符 | LEFT(‘abcde’,3) | abc |
| RIGHT(str,len) | 右起 len 个字符 | RIGHT(‘abcde’,3) | cde |
| SUBSTRING(str,pos,len) | 从 pos 开始取 len 个(pos 从 1 开始) | SUBSTRING(‘abcde’,2,3) | bcd |
| TRIM([BOTH] ‘x’ FROM str) | 去掉两边指定字符,默认空格 | TRIM(‘ abc ‘) | abc |
| LTRIM / RTRIM | 去左/去右空格 | ||
| REPLACE(str,from,to) | 替换所有 from 为 to | REPLACE(‘aaabbb’,’a’,’x’) | xxxbbb |
| UPPER(str) / LOWER(str) | 大小写转换 | UPPER(‘Abc’) | ABC |
| LENGTH(str) | 字节长度(中文占 3) | LENGTH(‘中国’) | 6 |
| CHAR_LENGTH(str) | 字符长度(中文占 1) | CHAR_LENGTH(‘中国’) | 2 |
2. 数值函数(TOP8)
| 函数 | 说明 | 示例 |
|---|---|---|
| ROUND(x,d) | 四舍五入,d 小数位 | ROUND(3.14159,2) → 3.14 |
| CEIL(x) / FLOOR(x) | 向上/向下取整 | CEIL(3.01) → 4 |
| TRUNCATE(x,d) | 直接截断,不四舍五入 | TRUNCATE(3.14159,2) → 3.14 |
| ABS(x) | 绝对值 | ABS(-5) → 5 |
| RAND() | 0~1 随机小数 | RAND() |
| MOD(a,b) | 取模(余数) | MOD(10,3) → 1 |
| POW(x,y) | x 的 y 次方 | POW(2,10) → 1024 |
| GREATEST / LEAST | 多值取最大/最小 | GREATEST(1,5,3) → 5 |
3. 日期时间函数(TOP15,超级高频!)
| 函数 | 说明 | 示例结果 |
|---|---|---|
| NOW() / CURRENT_TIMESTAMP | 当前日期时间 | 2026-01-22 18:45:30 |
| CURDATE() / CURRENT_DATE | 当前日期 | 2026-01-22 |
| CURTIME() | 当前时间 | 18:45:30 |
| DATE_ADD(date, INTERVAL 1 DAY) | 日期加减 | 2026-01-23 |
| DATE_SUB(date, INTERVAL 1 MONTH) | 2025-12-22 | |
| DATEDIF(date1,date2,’d’) | MySQL 无此函数!用 TIMESTAMPDIFF | |
| TIMESTAMPDIFF(unit,datetime1,datetime2) | 计算两个日期差(年月日时分秒) | TIMESTAMPDIFF(DAY,’2026-01-01′,’2026-01-22′) → 21 |
| DATE_FORMAT(date,’%Y-%m-%d %H:%i:%s’) | 格式化输出 | 2026-01-22 18:45 |
| STR_TO_DATE(str,format) | 字符串转日期 | STR_TO_DATE(‘2026/01/22′,’%Y/%m/%d’) |
| YEAR/MONTH/DAY/HOUR/MINUTE/SECOND(date) | 取年月日时分秒 | YEAR(NOW()) → 2026 |
| UNIX_TIMESTAMP() | 当前时间戳(秒) | 1737581130 |
| FROM_UNIXTIME(unix_timestamp) | 时间戳转日期 | 2026-01-22 18:45:30 |
4. 条件判断函数(神级)
| 函数 | 说明 | 示例 |
|---|---|---|
| IF(expr1,expr2,expr3) | 三元运算 | IF(1>0,’真’,’假’) → ‘真’ |
| IFNULL(expr1,expr2) | expr1 为 NULL 返回 expr2 | IFNULL(NULL,’默认’) → ‘默认’ |
| NULLIF(expr1,expr2) | expr1=expr2 返回 NULL,否则返回 expr1 | NULLIF(‘A’,’A’) → NULL |
| CASE WHEN … THEN … ELSE … END | 多条件判断(SQL 版 switch) | 见下面实战 |
5. 聚合函数(分组必备)
COUNT、SUM、AVG、MAX、MIN、GROUP_CONCAT(字段 SEPARATOR ‘,’) → 超级好用!
二、内外连接全家福(背会这张表就够了)
| 连接类型 | 写法1(SQL99) | 写法2(SQL92,老项目常见) | 结果说明 | 使用频率 |
|---|---|---|---|---|
| 内连接 | INNER JOIN … ON | WHERE a.id = b.id | 两表匹配的记录(交集) | ★★★★★ |
| 左外连接 | LEFT JOIN … ON | WHERE a.id = b.id(+) (Oracle 语法) | 左表全部 + 右表匹配的(右表无匹配补 NULL) | ★★★★★ |
| 右外连接 | RIGHT JOIN … ON | WHERE a.id = (+ )b.id (Oracle) | 右表全部 + 左表匹配的(左表无匹配补 NULL) | ★★★★☆ |
| 全外连接 | FULL OUTER JOIN … ON | MySQL 不支持!用 UNION 模拟 | 两表全部记录,无匹配补 NULL | ★★☆☆☆ |
| 左连接排除交集 | LEFT JOIN … ON … WHERE b.id IS NULL | 左表有但右表没有的记录(左差集) | ★★★★☆ | |
| 右连接排除交集 | RIGHT JOIN … ON … WHERE a.id IS NULL | 右表有但左表没有的记录(右差集) | ★★★☆☆ | |
| 全外排除交集 | FULL JOIN + WHERE a.id IS NULL OR b.id IS NULL | UNION 模拟 | 两表互不相同的记录(对称差集) | ★★★☆☆ |
经典案例:查询所有学生(包括没选课的)和他们的成绩
-- 左连接(最常用写法)
SELECT s.*, c.course_name, sc.score
FROM student s
LEFT JOIN score sc ON s.id = sc.student_id
LEFT JOIN course c ON sc.course_id = c.id;
查询没选课的学生(左连接排除交集)
SELECT s.*
FROM student s
LEFT JOIN score sc ON s.id = sc.student_id
WHERE sc.student_id IS NULL;
MySQL 模拟全外连接(不支持 FULL JOIN)
SELECT * FROM A LEFT JOIN B ON A.id=B.id
UNION
SELECT * FROM A RIGHT JOIN B ON A.id=B.id;
三、2026 年最实用的 5 个组合技巧
- GROUP_CONCAT + CASE WHEN 实现一行多列转一行一列(神技)
- IFNULL + COALESCE 防止 NULL 污染
- DATE_FORMAT + GROUP BY 按年月统计
- LEFT JOIN + IS NULL 查“有A无B”数据
- TIMESTAMPDIFF + INTERVAL 动态时间段统计
把上面这些函数和连接方式记熟,MySQL 面试题基本秒杀,日常开发也够用 95% 以上了!
需要我给你出 20 道经典 MySQL 面试题(带答案)练手吗?随时说~