暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

阿里云瑶池数据库SQL挑战赛!答题!

原创 无畏 2023-06-15
606

第一题

编写一个SQL查询,找出每个考试中 得分最高的的考生 。

DMS截图


SQL源码

SELECT
Test.name AS TestName,
Student.name AS StudentName,
BestScore.score AS Score
FROM
(
SELECT
studentId,
testId,
MAX(score) AS score
FROM
TestAttempt
GROUP BY
studentId, testId
) AS BestScore
JOIN TestAttempt ON BestScore.studentId = TestAttempt.studentId AND BestScore.testId = TestAttempt.testId AND BestScore.score = TestAttempt.score
JOIN Test ON Test.id = TestAttempt.testId
JOIN Student ON Student.id = TestAttempt.studentId
WHERE
(TestAttempt.testId, BestScore.score) IN (
SELECT
testId,
score
FROM
(
SELECT
testId,
studentId,
score,
DENSE_RANK() OVER (PARTITION BY testId ORDER BY score DESC) AS ExamRank
FROM
(
SELECT
studentId,
testId,
MAX(score) AS score
FROM
TestAttempt
GROUP BY
studentId, testId
) AS BestScores
) AS T
WHERE
ExamRank <= 3
)
ORDER BY
Test.name, BestScore.score DESC;

解题思路

可以使用窗口函数 DENSE_RANK() 对每门考试中的学生成绩进行排名,同时使用 PARTITION BY 定义每门考试作为一个分区;

然后从 Test 表和上一步得到的分数排名结果中 JOIN 出每个考试对应的前三名考生的信息;

最后在最外层查询中,根据排名确定每门考试的得分最高的学生,并按照要求返回结果表。


第二题

编写一个 SQL 查询,报告在首次游玩后的一周内至少再有一次游玩的玩家的比例,也就是注册首周内至少有两次登录的玩家占总玩家的比例,四舍五入到小数点后两位。

DMS截图


SQL源码

SELECT
ROUND(
(SELECT COUNT(DISTINCT player_id)
FROM
(SELECT player_id
FROM Activity
WHERE DATEDIFF(event_date,
(SELECT MIN(event_date)
FROM Activity AS a
WHERE a.player_id = Activity.player_id)) BETWEEN 1 AND 7
) AS WithinWeekPlayers
)
/
(SELECT COUNT(DISTINCT player_id) FROM Activity), 2
) AS PlayerRatio

解题思路

1. SELECT MIN(event_date) FROM Activity AS a WHERE a.player_id = Activity.player_id 查找每个玩家的首次游玩日期。

2. DATEDIFF(event_date, <首次游玩日期>) BETWEEN 1 AND 7 确定首次游玩后的一周内的活动。

3. SELECT COUNT(DISTINCT player_id) FROM <步骤2的结果> 计算在首次游玩后的一周内至少再有一次游玩的玩家数量。

4. SELECT COUNT(DISTINCT player_id) FROM Activity 计算总玩家数量。

5. 步骤3的结果 / 步骤4的结果 得出在首次游玩后的一周内至少再有一次游玩的玩家的比例。

6. ROUND(<步骤5的结果>, 2) 将结果四舍五入到小数点后两位。


第三题

写一个SQL查询,计算每个三角形的面积,保留两位小数。

DMS截图


SQL源码

SELECT
d.id, ROUND(0.5 * SQRT(pow(a, 2) + pow(b, 2) + pow(c, 2)), 2) AS area
FROM (
SELECT triangle.id
, (p2.y - p1.y) * (p3.z - p1.z) - (p3.y - p1.y) * (p2.z - p1.z) AS a
, (p2.z - p1.z) * (p3.x - p1.x) - (p2.x - p1.x) * (p3.z - p1.z) AS b
, (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y) AS c
FROM triangle
JOIN point p1 ON pointid1 = p1.id
JOIN point p2 ON pointid2 = p2.id
JOIN point p3 ON pointid3 = p3.id
) d
ORDER BY d.id;

解题思路

计算三角形面积的一种常见方法是使用海伦公式,但在三维空间中,我们不能直接使用它。

首先计算出每个三角形每条边的长度,然后利用向量积的长度公式计算三角形的面积.

首先通过JOIN操作获取每个三角形三个顶点的坐标,然后利用向量积的长度公式计算面积,最后使用ROUND函数将结果保留到小数点后两位。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论