写这篇博客的目的完全来自于我朋友圈里的一个朋友的评论。他半开玩笑地说,你试试用SQL查一下科比和勒布朗总共获得的总冠军数。我是一名资深的NBA球迷,也是科比的球迷,所以我觉得用我的专业技能之一的SQL来满足这种“玩笑”的需求是非常有趣的。
2.建表前言:建表规范
以下规范引用自《阿里巴巴Java开发手册v1.4.0》
2.1 创建表、字段和索引
我们可以创建一个名为 nba 的数据库。
创建一个名为的表,其中有玩家ID pid(int)为主键,玩家名称(name),字段()等字段。
然后创建一个名为team的表,主要包含球队ID tid(int)、球队名称name()、city()等;由于同一城市不可能有同名的球队,因此可以比较名称和城市,并在字段上创建唯一索引。
由于和球队是多对多的关系,所以我们肯定需要创建一个中间表,主要包括主键ptid(int)、球员pid(int)、球队tid(int)和年份(int)。这个中间表可以显示哪个球员在哪一年在哪支球队;因此可以为pid、tid、year这三个字段创建唯一索引。
和 是后面要创建的外键,默认也会添加普通索引。
最后,我们需要创建一个表,称为冠军表。这个表不需要主键,包括year(唯一索引,int)、team(int,对应球队tid)、决赛fmvp(int,对应选手pid)。字段。
同理nba球员数据查询,如果 和 是后面要创建的外键,也会默认添加普通索引。
2.2 创建外键
完成上述工作后,需要根据表之间的一对多关系添加外键。
如图所示,外键建立如下:
分别在表上创建 和 和 team 表的外键:
分别在表上创建 和 和 team 表的外键:
添加外键后nba球员数据查询,在架构设计器中将显示表之间的关系,如下所示:
3.插入数据
我们可以根据自己对NBA球星的喜好来插入数据,但是请注意,插入的数据必须对最终的查询结果有一定程度的干扰;在干扰数据下仍能找到正确的结果,保证了SQL的严谨性。例如nba球员数据查询,你可以在中间表中插入科比和勒布朗未夺冠年份效力的球队:2006年和2007年,科比,pid为1的球员,在湖人队,tid的球队1,而在2009年、2010年,pid为2的布朗球员勒布朗在骑士队,这是一支tid为4的球队。您还可以在表中插入干扰数据:来自2000年至2002年,fmvp(pid)为4的球员奥尼尔随队(tid)为1的湖人队夺得总冠军和FMVP。
4. SQL查询 4.1 查询冠军状态
我们不能急于查出科比和勒布朗获得了多少个总冠军,但我们可以看看他们夺冠的年份、当年的夺冠球队和FMVP,这样我们就可以先有个大概了:
SELECT c.year, kl.pid, kl.player_name, kl.team_name, p2.name fmvp
FROM champion c INNER JOIN
(SELECT p.pid, p.name player_name, pt.year, t.tid, t.name team_name
FROM player p
INNER JOIN player_team pt
ON p.pid = pt.pid
INNER JOIN team t
ON pt.tid = t.tid
WHERE p.name = 'Kobe Bryant' OR p.name = 'Lebron James') kl
INNER JOIN player p2
ON c.year = kl.year AND c.team = kl.tid AND c.fmvp = p2.pid
order by c.year;
查询结果如下:
查询结果完全正确!
4.2 查询冠军数量
拿下这颗定心丸后,我们可以直接查看两人获得的冠军数量:
SELECT kl.player_name player, COUNT(*) champions
FROM champion c INNER JOIN
(SELECT p.pid, p.name player_name, pt.year, t.tid
FROM player p
INNER JOIN player_team pt
ON p.pid = pt.pid
INNER JOIN team t
ON pt.tid = t.tid
WHERE p.name = 'Kobe Bryant' OR p.name = 'Lebron James') kl
ON c.year = kl.year AND c.team = kl.tid
GROUP BY kl.pid, kl.player_name;
查询结果如下,完全正确:
4.3 复活节彩蛋
阿伦·艾弗森是除了科比之外我最敬佩的后卫之一。在节奏缓慢、空间拥挤的21世纪初,他却能够四次夺得得分王。如果AI能够来到当今快节奏、体毛多的时代,如果给予绝对的球权,他能否成为场均40+的高效得分机器?
SELECT p.name, p.position, CONCAT(t.city, ' ', t.name) team FROM player p
INNER JOIN player_team pt ON p.pid = pt.pid
INNER JOIN team t ON pt.tid = t.tid
WHERE p.name = 'Allen Iverson';
5.源码下载
本文相关的SQL已经上传到我的码云,点击nba文件夹即可;对NBA和SQL感兴趣的朋友可以下载来玩。
• 本站声明:以上部分图文视频来自网络,如涉及侵权请联系删除。