SQL查询语句详细知识总结--轻松解决力扣高频SQL50题
SQL查询语句详细知识总结--轻松解决力扣高频SQL50题
SQL(Structured Query Language)是操作关系型数据库的核心语言,其查询功能是数据分析、数据提取的关键。本文系统总结SQL查询语句的知识点,涵盖基础查询、条件过滤、聚合分组、多表查询等核心内容,并结合实例说明。注意:本文只讲SQL查询,增删改操作简单就略过。认真看完这篇文章,轻松解决力扣高频SQL50题。
一、基础查询
1. SELECT语句结构
SELECT 列名1, 列名2... FROM 表名;
- 查询所有列
SELECT * FROM 表名;
- 查询指定列
SELECT name, age FROM students;
2. 别名与计算字段
- 列别名
SELECT name AS 姓名, age+1 AS 新年龄 FROM students;
- 常量表达式
SELECT '2025年数据' AS 备注, age FROM students;
AS可以忽略不写,MYSQL中不区分大小写。
二、条件过滤(WHERE子句)
1. 运算符
- 比较运算符
=, >, <, !=(不等于)
- 逻辑运算符
AND, OR, NOT
- 范围查询
BETWEEN...AND...(闭区间)
SELECT * FROM students WHERE age BETWEEN 18 AND 25;
- 集合查询
IN
SELECT * FROM students WHERE university IN ('北京大学', '清华大学');
SELECT * FROM students WHERE (id, university) IN ((101,'北京大学'), (102,'清华大学'));
2. 模糊查询(LIKE)和 (LIKE CONCAT)
%
:匹配任意字符(包括空字符),如 LIKE '%北京%' 匹配包含“北京”的字符串。_
:匹配单个字符,如 LIKE '_张%' 匹配第二个字符为“张”的字符串
(1)LIKE 的典型用法
直接指定固定模式进行模糊匹配:
SELECT * FROM users
WHERE name LIKE '张%'; -- 匹配以“张”开头的名字
(2)CONCAT + LIKE 的典型用法
动态拼接模式(常用于参数化查询或复杂条件):
-- 假设变量 @keyword = '北京'
SELECT * FROM users
WHERE city LIKE CONCAT('%', @keyword, '%'); -- 匹配包含“北京”的城市名
此时 CONCAT('%', @keyword, '%') 生成 '%北京%',等同于直接写 LIKE '%北京%',但更灵活。
(3)关键区别详解
- 动态性
- LIKE:模式通常是静态的(硬编码在SQL中)。
- CONCAT + LIKE:允许动态生成模式(结合变量、字段值或其他函数)。
- 参数化查询
当使用编程语言(如 Java、Python)拼接 SQL 时,CONCAT 可避免 SQL 注入风险:
-- Python 示例(安全写法)
sql = "SELECT * FROM users WHERE name LIKE CONCAT('%', %s, '%')"
cursor.execute(sql, (user_input,))
- 跨数据库兼容性
- MySQL:支持 CONCAT(str1, str2)。
- SQL Server:使用 + 拼接字符串(如 '%' + @keyword + '%')。
- Oracle:使用 || 拼接字符串(如 '%' || :keyword || '%')。
3. 空值处理
- IS NULL:筛选空值,如:
SELECT * FROM students WHERE gender IS NULL;
- IS NOT NULL:排除空值
三、聚合与分组(GROUP BY & HAVING)
1. 聚合函数
- COUNT():统计行数(COUNT(*)包含NULL,COUNT(列名)排除NULL)。
- SUM()、AVG()、MAX()、MIN():数值型数据的统计
SELECT university, AVG(gpa) AS 平均GPA FROM user_profile GROUP BY university;
2. 分组查询(GROUP BY)
以这个表数据为例:
单列分组:
双列分组:
3. 分组过滤(HAVING)
- 与WHERE的区别:WHERE 过滤行,HAVING 过滤分组。
SELECT university, AVG(gpa)
FROM user_profile
GROUP BY university
HAVING AVG(gpa) > 3.5; -- 筛选平均GPA大于3.5的学校。
四、多表查询(JOIN与子查询)
1. 表连接类型
- 内连接(INNER JOIN / JOIN):返回两表交集数据。
- 左连接(LEFT JOIN):保留左表所有记录,右表无匹配则补NULL。
- 右连接(RIGHT JOIN):保留右表所有记录
- 全连接(INNER JOIN + RIGHT JOIN):保留两个表的完整数据
内连接,基于连接条件筛选两表中匹配的行,形成交集数据
SELECT s.name, c.class_name
FROM students s
INNER JOIN classes c ON s.class_id = c.id;
要实现保留两个表的完整数据(即全外连接),需同时包含两表中未匹配的行。由于 MySQL**不支持
FULL OUTER JOIN
**,可通过
LEFT JOIN + RIGHT JOIN + UNION
组合实现。以下是具体步骤和示例:
-- 保留所有学生和匹配的班级(左连接)
SELECT s.name, c.class_name
FROM students s
LEFT JOIN classes c ON s.class_id = c.id
UNION -- 去重合并
-- 保留所有班级和匹配的学生(右连接)
SELECT s.name, c.class_name
FROM students s
RIGHT JOIN classes c ON s.class_id = c.id;
2. 子查询
- WHERE子句中嵌套
SELECT * FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
- FROM子句中嵌套(派生表)
SELECT dept, avg_salary
FROM (SELECT dept, AVG(salary) AS avg_salary FROM employees GROUP BY dept) AS t;
五、结果排序与限制(ORDER BY & LIMIT)
1. 排序(ORDER BY)
不写默认升序
- 单列排序
SELECT * FROM students ORDER BY age DESC;(降序)
- 多列排序
SELECT * FROM students ORDER BY gpa DESC, age ASC;
2. 分页(LIMIT)
- 基本语法:LIMIT 起始行, 行数 或 LIMIT 行数 OFFSET 起始行。
SELECT * FROM students LIMIT 5; -- 取前5行数据
SELECT * FROM students LIMIT 10, 5; -- 跳过前10行,取5行数据
SELECT * FROM students LIMIT 5 OFFSET 10; -- 跳过前10行,取5行数据
六、窗口函数(高级查询)
窗口函数是 SQL 中用于对结果集的子集(窗口)进行复杂计算的工具,尤其适用于排名、累计统计等场景。以下是
ROW_NUMBER()
、
RANK()
和
DENSE_RANK()
的核心区别、用法及实例分析:
函数定义与核心区别
函数 描述 示例排序结果
ROW_NUMBER() 为每一行分配唯一序号,即使值相同,序号也不重复。 1, 2, 3, 4
RANK() 允许并列排名,但后续名次会跳过并列占用的位置。 1, 1, 3, 4
DENSE_RANK() 允许并列排名,后续名次连续不跳跃。 1, 1, 2, 3
核心差异:
- 并列处理:
RANK()
和
DENSE_RANK()
允许并列,但
RANK()
会跳跃后续名次,而
DENSE_RANK()
保持连续。 - 唯一性:
ROW_NUMBER()
强制生成唯一序号,不处理并列
七、联合查询(UNION / UNION ALL)
合并多个SELECT结果集(需列数一致):
SELECT name FROM students
UNION
SELECT name FROM teachers; -- 默认去重,使用UNION ALL保留重复。
union 和 union all 的区别:
unino 在进行数据连接后,在进行一次过滤操作,除去重复的数据;而 union all 没有过滤操作
八、常用函数
1.数字函数
(1)四舍五入和取整:
round(123.45678, 2) // 123.46(保留两位小数)
ceil(123.1) // 124(向上取整)
floor(123.9) // 123(向下取整)
(2)计算和转换:
abs(-5) // 5(绝对值)
power(2, 3) // 8(幂运算)
rand() // 生成0-1的随机数
2.字符串函数
(1)拼接和截取:
concat(str1, str2) // 字符串拼接
substring(str, start, length) // 截取字串
在MySQL中,处理字符串时使用的位置参数(如函数中的起始位置)均以1作为第一个字符的索引,而非从0开始。
(2)格式处理:
upper() / lower() // 大小写转化
trim() / ltrim() / rtrim() // 去除空格
3.日期时间函数:
处理日期和时间的操作很重要,核心函数如下:
(1)当前时间获取:
now() // 当前日期时间(如'2025-03-09 14:30:45')
curdate() / curtime() // 当前日期或当前时间
(2)日期提取和格式化:
year(date) / month(date) / day(date) // 提取年/月/日
date_format(date, '%Y-%m-%d') // 自定义格式输出
extract(year from date) // 标准化提取时间单位
(3)日期计算:
date_add(date, Interval n day) // 增加n天
datediff(end_date, start_date) // 计算天数差
timestampiff(hour, start_time, end_time) // 跨单位差值
总结:SQL作为关系型数据库的核心查询语言,通过灵活组合
SELECT
语句、
JOIN
多表关联、
WHERE
条件过滤、
GROUP BY
聚合统计及窗口函数等操作,能够高效完成从基础数据检索到复杂分析的各类需求。掌握本文核心知识点(如索引优化、多表连接逻辑、窗口函数排名规则等),可轻松应对力扣高频SQL题、日常数据分析及面试考察,同时为进阶学习(如递归查询、执行计划优化)奠定坚实基础,真正实现“一技在手,数据无忧”!