趣味MySQL:查询NBA球员的冠军总数

1. Kobe or Lebron?

写这篇博客的目的完全来自于一位朋友在我朋友圈的评论,他半开玩笑地说,你试试用SQL查出科比和勒布朗的夺冠总数。我是一个资深NBA球迷,同时也是科蜜(科比.布莱恩特的球迷),所以我觉得用我的职业技术之一SQL来做这个“玩笑”式的需求,非常有趣。在这里插入图片描述

2. 建表

前言:建表的规范

以下规范均引用自《阿里巴巴 Java开发手册 v1.4.0》
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1 创建表、字段和索引

咱们可以创建一个数据库叫nba。
建立一张表叫player,里面有球员ID pid(int)作为主键,球员姓名name(varchar),场上位置position(varchar)等字段。
然后再建立一张表叫team,主要包括球队ID tid(int),队名name(varchar),所在城市city(varchar)等;由于同城不能有重名的球队,所以可以对name和city两个字段建立唯一索引city_name。
在这里插入图片描述
由于player和team是多对多关系,所以我们肯定需要建立一张中间表叫player_team,主要包括主键ptid(int),球员pid(int), 球队tid(int)以及年份year(int),这种中间表可以展示哪一年哪位球员在哪只球队;所以对于pid, tid, year三个字段可以建立唯一索引。
在这里插入图片描述
fk_pid和fk_tid是后面要建立的外键,也会被默认添加普通索引。
最后我们需要建立一张表叫夺冠表champion,这个表可以不用主键,包括年份year(唯一索引, int),球队team(int,对应球队tid),总决赛fmvp(int,对应球员pid)三个字段。
在这里插入图片描述
同理,fk_fmvp_pid和fk_team_tid是后面要建立的外键,也会被默认添加普通索引。

2.2 创建外键

上述工作做完后,需要根据表之间的一对多关系添加外键。
如图,建立外键如下:
在champion表上分别建立与player和team表的外键fk_fmvp_pid和fk_team_tid:
在这里插入图片描述
在player_team表上分别建立与player和team表的外键fk_pid和fk_tid:
在这里插入图片描述
外键添加完后,在SQLyog的架构设计器中显示各表之间的关系如下:
在这里插入图片描述

3. 插入数据

咱们可以根据自己对NBA球星的喜好来插入数据,但是请注意插入的数据要对最终的查询结果有一定的干扰性;在干扰数据下仍能查出正确结果,可以确保SQL的严谨性。比如,可以在中间表player_team插入科比和勒布朗没有夺冠的年份所在的球队:2006,2007年pid为1的球员科比在tid为1的球队湖人队,2009,2010年pid为2的球员勒布朗在tid为4的球队骑士队。还可以在champion表中插入干扰数据:2000 ~ 2002年fmvp(pid)为4的球员奥尼尔在team(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感兴趣的朋友可以下载下来玩玩。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的 MySQL 数据库管理系统的例子,用于管理NBA球员的数据: 首先,创建一个名为 `nba_players` 的数据库: ``` CREATE DATABASE nba_players; ``` 然后,创建一个名为 `players` 的表格,用于存储球员的基本信息: ``` USE nba_players; CREATE TABLE players ( id INT PRIMARY KEY, name VARCHAR(50), age INT, team VARCHAR(50), position VARCHAR(50), height INT, weight INT ); ``` 接下来,向 `players` 表格中添加数据: ``` INSERT INTO players (id, name, age, team, position, height, weight) VALUES (1, 'LeBron James', 35, 'Los Angeles Lakers', 'SF', 203, 113), (2, 'Kawhi Leonard', 28, 'Los Angeles Clippers', 'SF', 201, 102), (3, 'Giannis Antetokounmpo', 25, 'Milwaukee Bucks', 'PF', 211, 109), (4, 'James Harden', 30, 'Houston Rockets', 'SG', 196, 100), (5, 'Stephen Curry', 31, 'Golden State Warriors', 'PG', 191, 86); ``` 现在,我们可以使用 SQL 查询语句来对球员数据进行管理。例如,我们可以使用以下语句来查询所有球员的基本信息: ``` SELECT * FROM players; ``` 我们也可以使用 WHERE 子句来筛选数据,例如只查询年龄大于等于 30 岁的球员: ``` SELECT * FROM players WHERE age >= 30; ``` 还可以使用 UPDATE 语句来更新数据。例如,将球员 LeBron James 的身高更新为 205 厘米: ``` UPDATE players SET height = 205 WHERE name = 'LeBron James'; ``` 最后,我们可以使用 DELETE 语句来删除数据。例如,删除年龄小于 30 岁的球员: ``` DELETE FROM players WHERE age < 30; ``` 这只是一个简单的例子,实际上一个完整的 NBA 球员数据库管理系统可能需要更多的表格和更复杂的查询语句。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值