SQLite是世界上最广泛部署的关系型数据库之一,它不需要单独的服务器进程,整个数据库就是一个文件,非常适合学习和小型项目。但光看语法文档远远不够,想要真正掌握SQL,必须通过大量练习题把知识内化。本文按照从入门到精通的顺序,整理一条完整的SQLite练习路径,并给出典型题目和参考解法,你可以边看边在自己的电脑上动手跑一遍。

第一步:搭建练习环境,熟悉基础SQL语句
练习SQLite的第一步是准备环境。推荐直接去官网下载sqlite3命令行工具,解压后就可以使用,没有任何安装配置。打开终端输入sqlite3 test.db即可创建并连接一个数据库文件。当然,如果你更喜欢图形界面,DB Browser for SQLite和Navicat都是不错的选择,看表结构和数据会更直观。环境准备好之后,先建几张练习用的表,比如学生表、课程表和成绩表,这是后续所有练习题的基础。
入门阶段的练习题应聚焦在单表操作上,重点是INSERT、UPDATE、DELETE和最基础的SELECT。比如:向学生表插入五条记录;把某个学生的年龄更新为20;删除成绩低于60分的记录;查询所有女生并按年龄降序排列。这些题目看似简单,却是打牢基本功的关键。下面是一份建表和基础查询的示例代码。
CREATE TABLE student (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
gender TEXT,
age INTEGER,
class_id INTEGER
);
-- 插入练习数据
INSERT INTO student (name, gender, age, class_id) VALUES
('张三', '男', 18, 1),
('李四', '女', 19, 2),
('王五', '男', 20, 1);
-- 练习题:查询年龄大于18的学生,按年龄降序
SELECT name, age FROM student
WHERE age > 18
ORDER BY age DESC
LIMIT 10;这个阶段建议给自己定个目标,比如连续三天每天完成二十道单表查询题。可以自己造数据,也可以到网上找现成的SQLite示例数据库,比如Chinook这个音乐数据库,它包含多张关联表和真实感的数据,非常适合练手。做错不要紧,关键是搞清楚WHERE的过滤顺序、NULL值在比较中的特殊行为这些容易踩坑的细节。
第二步:进阶多表查询,掌握连接与聚合
单表查询熟练之后,就该进入多表操作了,这也是面试和实际开发中的重头戏。练习题应该围绕JOIN展开:内连接查询每个学生的班级名称;左连接找出没有选课的学生;自连接查询员工表中每个员工及其上级的姓名。特别是LEFT JOIN配合WHERE判断NULL,是找出孤立记录的经典套路,一定要练到滚瓜烂熟。
聚合统计类练习题同样重要。常见的题目包括:统计每个班级的学生人数;查询平均分超过80分的课程;找出总成绩最高的前三名学生。这类题目的核心是GROUP BY和HAVING的配合使用,很多人分不清WHERE和HAVING的区别,前者在分组前过滤行,后者在分组后过滤组,多做几道题自然就理解了。下面是一个典型的多表聚合练习。
-- 练习题:查询每个班级的平均年龄,只保留平均年龄大于18的班级 SELECT c.class_name, AVG(s.age) AS avg_age FROM student s JOIN class c ON s.class_id = c.id GROUP BY c.class_name HAVING AVG(s.age) > 18 ORDER BY avg_age DESC; -- 练习题:查询没有选修任何课程的学生(LEFT JOIN经典用法) SELECT s.name FROM student s LEFT JOIN score sc ON s.id = sc.student_id WHERE sc.id IS NULL;
建议在这个阶段刻意练习题目的变形。比如同样是统计每个班级的人数,试着分别用COUNT(*)和COUNT(字段)写一遍,观察结果差异;再尝试给统计结果加上排名,这会引出窗口函数。SQLite从3.25版本开始支持ROW_NUMBER、RANK等窗口函数,掌握它们能让你的SQL表达能力上一个台阶。
第三步:冲刺精通,练习子查询、事务与性能优化
到了高级阶段,练习重点从会写转向写得好。子查询方面的题目包括:用子查询找出成绩高于全班平均分的学生;用EXISTS改写IN子查询并对比性能;用相关子查询实现每组取前N名的需求。写完之后可以把子查询改写成JOIN形式,对比两种写法的执行计划,体会查询优化器的取舍。
事务和性能优化也是精通路上绕不开的内容。练习题可以设计成这样:模拟转账场景,用BEGIN、COMMIT、ROLLBACK保证两条UPDATE要么都成功要么都失败;然后故意制造错误,观察回滚效果。性能方面,先建一张百万行的表,在没有索引的情况下执行某个条件查询并计时,再用CREATE INDEX建立索引后重复查询,直观感受索引带来的速度差异。示例代码如下。
-- 事务练习:转账操作,保证原子性 BEGIN; UPDATE account SET balance = balance - 100 WHERE id = 1; UPDATE account SET balance = balance + 100 WHERE id = 2; COMMIT; -- 出错时改用ROLLBACK撤销操作 -- 索引练习:为经常查询的字段建索引 CREATE INDEX idx_student_class ON student(class_id); -- 查看查询计划,分析是否用上了索引 EXPLAIN QUERY PLAN SELECT * FROM student WHERE class_id = 1;
当你能独立完成建库、设计表结构、编写复杂查询、分析执行计划并优化索引这整套流程时,就基本达到精通水平了。后续可以继续深入学习CTE递归查询、JSON扩展、全文检索FTS5等SQLite的高级特性,也可以把练习成果应用到一个真实的小项目中,比如做个记账本或待办事项应用。记住,SQL是练出来的不是看出来的,保持每天做题的习惯,两三个月就能看到质的飞跃。