- 查询不在表里的数据,一张学生表,一张学生的选课表,要求查出没有选课的学生?
select students.student_name from students left join course_selection on students.student_id=course_selection.student_id where course_selection.student_id is null
- 查找第N高的数据,查找课程编号为”01“的成绩第三高的学生,如果不存在则返回null
select IFNULL((select scores.score from scores order by scores.score desc limit 1 offset 2) ,null) as "第三高的成绩"
- 分组排序,按成绩从大到小排序如80,80,76,70,50 对应的排序为1,1,3,4,5
select *,RANK() over(ORDER BY scores.score DESC) as "排名" from scores
- 连续出现N次问题,学生连续3个学号相邻的学生出现年龄相同的年龄
select distinct a.age from students a,students b,students c where a.student_id=b.student_id+1 and b.student_id=c.student_id+1 and a.age=b.age and b.age=c.age
常见知识点:
1. 多层嵌套子查询 + 聚合函数
题目:查询订单总额高于该客户平均订单金额的所有订单
SELECT order_id, customer_id, total_amount
FROM orders o1
WHERE total_amount > (
SELECT AVG(total_amount)
FROM orders o2
WHERE o2.customer_id = o1.customer_id
);
考点:关联子查询、聚合函数、比较运算符
2. 多表JOIN + 分组统计
题目:查询每个部门的最高薪员工信息
SELECT d.dept_name, e.emp_name, e.salary
FROM departments d
JOIN employees e ON d.dept_id = e.dept_id
WHERE e.salary = (
SELECT MAX(salary)
FROM employees
WHERE dept_id = d.dept_id
);
考点:内连接、相关子查询、分组极值
3. 窗口函数应用
题目:查询每个部门薪资排名前三的员工
SELECT dept_id, emp_name, salary
FROM (
SELECT *,
DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) as rk
FROM employees
) t
WHERE rk <= 3;
考点:窗口函数、排名函数、子查询
4. 递归查询层级数据
题目:查询某员工的所有下级(包含N级)
WITH RECURSIVE emp_tree AS (
SELECT emp_id, emp_name, manager_id
FROM employees
WHERE emp_id = 1001 -- 指定上级ID
UNION ALL
SELECT e.emp_id, e.emp_name, e.manager_id
FROM employees e
JOIN emp_tree et ON e.manager_id = et.emp_id
)
SELECT * FROM emp_tree;
考点:CTE递归查询、树形结构处理
5. 行转列动态查询
题目:动态生成各月销售额的列式报表
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'SUM(CASE WHEN MONTH(order_date) = ',
month,
' THEN amount ELSE 0 END) AS `',
month_name, '`'
)
) INTO @sql
FROM (
SELECT MONTH(order_date) month,
DATE_FORMAT(order_date, '%b') month_name
FROM orders
GROUP BY 1,2
) m;
SET @sql = CONCAT('SELECT product_id, ', @sql,
' FROM orders GROUP BY product_id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
考点:动态SQL、PIVOT转换、GROUP_CONCAT函数
6. 复杂日期处理
题目:查询连续3天登录的用户
SELECT DISTINCT a.user_id
FROM login_log a
JOIN login_log b ON a.user_id = b.user_id
AND b.login_date = DATE_ADD(a.login_date, INTERVAL 1 DAY)
JOIN login_log c ON a.user_id = c.user_id
AND c.login_date = DATE_ADD(a.login_date, INTERVAL 2 DAY);
考点:日期函数、自连接、连续性问题
7. 存在性检查
题目:查询购买了所有品类商品的客户
SELECT customer_id
FROM orders
GROUP BY customer_id
HAVING COUNT(DISTINCT category_id) = (
SELECT COUNT(DISTINCT category_id) FROM products
);
考点:HAVING子句、集合运算、全量存在判断
8. 分页性能优化
题目:高效实现千万级数据分页
SELECT id, name, create_time
FROM large_table
WHERE create_time > '2023-01-01'
ORDER BY create_time DESC, id DESC
LIMIT 10 OFFSET 100000;
考点:分页优化、索引设计、排序字段选择
9. 多重条件聚合
题目:统计各商品不同价格区间的销量
SELECT product_id,
SUM(CASE WHEN price < 100 THEN 1 ELSE 0 END) AS low_price,
SUM(CASE WHEN price BETWEEN 100 AND 500 THEN 1 ELSE 0 END) AS mid_price,
SUM(CASE WHEN price > 500 THEN 1 ELSE 0 END) AS high_price
FROM orders
GROUP BY product_id;
考点:条件聚合、CASE表达式
10. 数据去重保留最新
题目:删除重复订单(保留最新记录)
DELETE FROM orders
WHERE order_id NOT IN (
SELECT MAX(order_id)
FROM orders
GROUP BY customer_id, product_id, order_date
);
考点:数据去重、保留极值、子查询删除
11. 多结果集合并
题目:合并新老系统用户表(去重)
SELECT user_id, user_name FROM old_users
UNION
SELECT user_id, user_name FROM new_users;
考点:集合操作、UNION去重
12. 事务并发控制
题目:实现库存安全扣减
START TRANSACTION;
SELECT stock FROM products WHERE id=1001 FOR UPDATE;
UPDATE products SET stock = stock - 1 WHERE id=1001;
COMMIT;
考点:事务隔离、悲观锁、并发控制