当前位置:首页 > 问答 > 正文

学SQL Server那些练习题,边做边摸索的感觉还挺真实的

行,那我直接给你搬一些我觉得挺有“边做边摸索”感觉的SQL Server练习题和场景描述,这些内容混合了网上常见的练习思路和我自己以前学的时候碰到的情况,你就当是朋友给你分享的学习笔记吧。

来源说明:这部分练习思路参考了网上流传很广的“某培训机构SQL入门练习题”和博客园等技术社区里一些网友的自学记录。

最开始装好SQL Server Management Studio (SSMS) 那个大绿图标的时候,面对一个空白的查询窗口,真不知道从哪儿下手,光看理论说什么“数据库就是数据的仓库”太抽象了,就得有点具体的事儿做,我记得第一个有感觉的练习,是让我自己建一个最简单的学生表,教程上是这么说的:

“你先别管别人现成的数据库,自己动手创建一个表,就叫Students,里面得有学号(StudentID)、姓名(Name)、性别(Gender)、年龄(Age)这几个字段。”

然后我就开始敲代码:

CREATE TABLE Students (
    StudentID int PRIMARY KEY,
    Name nvarchar(50),
    Gender nchar(1),
    Age int
);

敲完按F5执行,左边对象资源管理器里一刷新,真的看到了我自己建的Students表,那个感觉一下就来了,好像有了块自己的地盘,但这只是个空架子,得往里加点数据,教程接着说:“你现在往里插几条记录,比如插入一个叫‘张三’的男生,20岁,学号是2023001。”

我就写:

INSERT INTO Students (StudentID, Name, Gender, Age)
VALUES (2023001, '张三', '男', 20);

一开始还老报错,不是忘了逗号就是单引号打成中文的了,摸索了几次才成功,插入了三五条数据后,最激动的时刻来了——执行我的第一个查询:

SELECT * FROM Students;

结果窗口那个表格真的把我刚输进去的数据整整齐齐地显示出来了!就这一下,SELECT语句是干嘛用的,瞬间就明白了,比看十遍定义都管用。

光查全部没意思,教程开始加条件了:“你试试只查年龄大于19岁的学生。”我就摸索着写:

SELECT * FROM Students WHERE Age > 19;

看着结果集变少了,WHERE的作用一下子就实在了,接着是模糊查询:“查所有姓‘张’的学生。”这就要用LIKE了:

SELECT * FROM Students WHERE Name LIKE '张%';

那个通配符,一开始总记混,试错两次就记住了。

光一个表玩不出花样,教程马上引入了第二个表——课程表Courses(课程号CourseID,课程名CourseName)和第三个表——成绩表Scores(学号StudentID,课程号CourseID,分数Score),建好表后,头疼的事儿来了:关联查询,教程说:“你现在要查每个学生的姓名和他们的成绩。”

学SQL Server那些练习题,边做边摸索的感觉还挺真实的

我一开始写成这样:

SELECT Name, Score FROM Students, Scores;

结果出来一堆乱七八糟的重复数据,这就是笛卡尔积,当时就懵了,然后教程才解释要关联条件,摸索着改成:

SELECT Students.Name, Scores.Score
FROM Students
INNER JOIN Scores ON Students.StudentID = Scores.StudentID;

当正确的、一一对应的结果出来时,对JOIN的理解深刻多了,这还没完,“那如果要查选了某门具体课程(数学’)的学生姓名和成绩呢?”这就需要在JOIN的基础上再加WHERE条件,或者把条件放在JOIN...ON后面,我两种都试了试,感觉还挺不一样的,摸索出什么时候用哪种写法更顺手。

来源说明:关于连接查询的常见错误和练习方法,参考了CSDN上《SQL连接查询经典例题》一文中的部分场景。

聚合函数也是边做边才摸出门道的,教程说:“你统计一下每门课程的平均分。”我就用到了GROUP BY

SELECT CourseID, AVG(Score) as AvgScore
FROM Scores
GROUP BY CourseID;

但光有课程号看不懂啊,我就想能不能把课程名也显示出来?这就需要用课程表Courses和成绩表Scores进行连接,然后再分组,这个查询我写了挺久,因为GROUP BY的字段要小心,不是SELECT里有的所有字段都能随便放的,失败了就报错,看错误信息再改,最后写出来的时候很有成就感。

子查询也是个大坎,教程问:“查出比平均年龄大的所有学生。”我第一反应是分开两步:先查平均年龄,再查大于这个数的,但教程要求用一条SQL完成,我抓耳挠腮,他盯着屏幕,试着把第一个查询的结果塞进第二个查询的条件里:

学SQL Server那些练习题,边做边摸索的感觉还挺真实的

SELECT * FROM Students WHERE Age > (SELECT AVG(Age) FROM Students);

执行成功那一刻,突然懂了什么叫“查询里面套查询”,那种层层剥开问题的逻辑感特别真实。

来源说明:关于数据修改和联表查询的复杂练习,参考了CSDN论坛里一个名为“SQL Server经典50题”的帖子中关于成绩管理的部分。

后来练习升级了,要建关联表,比如加一个Courses课程表和Scores成绩表,这时候JOIN操作就变得特别具体,比如要查“张三的数学成绩”,代码就变成了:

SELECT s.Name, c.CourseName, sc.Score
FROM Students s
INNER JOIN Scores sc ON s.StudentID = sc.StudentID
INNER JOIN Courses c ON sc.CourseID = c.CourseID
WHERE s.Name = '张三' AND c.CourseName = '数学';

写这种多表连接的时候,经常因为表别名搞混或者ON条件写错而报错,就得反复调试,哪个表连哪个字段,一点都不能错,这种摸索的过程,虽然折腾,但每解决一个错误,对表关系的理解就深一层。

还有数据更新和删除,带着条件操作时会特别小心,比如老师让“把李四的年龄改成21岁”,写UPDATE语句时,一定会再三确认WHERE条件是不是精准地锁定了“李四”,生怕一个手滑把全班都改了,这种紧张感,反而让人牢牢记住了数据操作的严肃性。

来源说明:关于使用聚合函数和分组统计的练习场景,融合了知乎答主“SQL实战心得”中提到的“从数据中挖信息”的案例。

最让我觉得像侦探破案的是用GROUP BY和聚合函数,比如分析“每个性别学生的平均年龄”:

SELECT Gender, AVG(Age) as AvgAge FROM Students GROUP BY Gender;

当看到结果里男女生平均年龄被计算出来时,感觉就像从一堆乱麻里抽出了线头,还有更复杂的,“查平均成绩大于80分的学生姓名和平均分”,需要HAVING子句过滤分组后的结果,写的时候才明白WHEREHAVING的区别——一个挑行,一个挑组。

这种边写代码边试错的过程,特别有实感,有时候脑子想不明白LEFT JOININNER JOIN区别,就干脆把两种都写一遍,对比结果集的差异,一下就通了,犯错,改错,再看结果,这个循环虽然枯燥,但每次成功跑出想要的数据时,那种“我搞懂了”的瞬间,就是学习最真实的反馈。