表: Scores
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| player_name | varchar |
| gender | varchar |
| day | date |
| score_points | int |
+---------------+---------+
(gender, day)是该表的主键
一场比赛是在女队和男队之间举行的
该表的每一行表示一个名叫 (player_name) 性别为 (gender) 的参赛者在某一天获得了 (score_points) 的分数
如果参赛者是女性,那么 gender 列为 'F',如果参赛者是男性,那么 gender 列为 'M'
写一条SQL语句查询每种性别在每一天的总分,并按性别和日期对查询结果排序
下面是查询结果格式的例子:
Scores表:
+-------------+--------+------------+--------------+
| player_name | gender | day | score_points |
+-------------+--------+------------+--------------+
| Aron | F | 2020-01-01 | 17 |
| Alice | F | 2020-01-07 | 23 |
| Bajrang | M | 2020-01-07 | 7 |
| Khali | M | 2019-12-25 | 11 |
| Slaman | M | 2019-12-30 | 13 |
| Joe | M | 2019-12-31 | 3 |
| Jose | M | 2019-12-18 | 2 |
| Priya | F | 2019-12-31 | 23 |
| Priyanka | F | 2019-12-30 | 17 |
+-------------+--------+------------+--------------+
结果表:
+--------+------------+-------+
| gender | day | total |
+--------+------------+-------+
| F | 2019-12-30 | 17 |
| F | 2019-12-31 | 40 |
| F | 2020-01-01 | 57 |
| F | 2020-01-07 | 80 |
| M | 2019-12-18 | 2 |
| M | 2019-12-25 | 13 |
| M | 2019-12-30 | 26 |
| M | 2019-12-31 | 29 |
| M | 2020-01-07 | 36 |
+--------+------------+-------+
女性队伍:
第一天是 2019-12-30,Priyanka 获得 17 分,队伍的总分是 17 分
第二天是 2019-12-31, Priya 获得 23 分,队伍的总分是 40 分
第三天是 2020-01-01, Aron 获得 17 分,队伍的总分是 57 分
第四天是 2020-01-07, Alice 获得 23 分,队伍的总分是 80 分
男性队伍:
第一天是 2019-12-18, Jose 获得 2 分,队伍的总分是 2 分
第二天是 2019-12-25, Khali 获得 11 分,队伍的总分是 13 分
第三天是 2019-12-30, Slaman 获得 13 分,队伍的总分是 26 分
第四天是 2019-12-31, Joe 获得 3 分,队伍的总分是 29 分
第五天是 2020-01-07, Bajrang 获得 7 分,队伍的总分是 36 分
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/running-total-for-different-genders
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
审题:写一条SQL语句查询每种性别在每一天的总分,并按性别和日期对查询结果排序
思考:按照日期排序,然后查询男女累计的结果。
解题:
方法一:连结两个表,性别相同,左表日期大于等于右表日期
对性别相同,该天以及该天之前的所有日期的分数求和。
SELECT s1.gender, s1.day, SUM(s2.score_points) total
FROM Scores s1, Scores s2
WHERE s1.gender = s2.gender AND s1.day >= s2.day
GROUP BY s1.gender, s1.day
ORDER BY s1.gender, s1.day
-- 练习
-- sql执行顺序是先分组,然后一条一条通过where判断。
SELECT s1.gender, s1.day, SUM(s2.score_points) total
from scores s1, scores s2
-- 性别相同,s1日期再s2日期之前
where s1.gender = s2.dender AND s1.day >= s2.day
-- 按照性别和日期分组
group by s1.gender,s1.day
order by s1.gender,s1.day
方法二:新增两个变量
1.先按gender, day排序
SELECT gender, day
FROM Scores
ORDER BY gender, day
2.增加两个变量:
第一个变量@total用来记录累计分数;
第二个变量@pre_gender用来记录前一条记录的性别。
如果性别与前一条记录的性别一样,分数累加;如果性别与前一条记录的性别不一样,分数重置。
SELECT gender, day,
CASE WHEN @pre_gender = gender THEN @total := @total + score_points
ELSE @total := score_points
END AS total,
@pre_gender := gender
FROM Scores,
(SELECT @total := 0, @pre_gender := NULL) as init
ORDER BY gender, day
-- 练习
select gender,day,
-- 通过判断性别,如果相同就在total结果加上本行
case when @pre_gender = gender then @total := @total + score_points
-- 如果性别不同,就直接赋值给total,因为最先按照性别排序,所以性别不同,就是一个性别结束了。
else @total := score_points end as total,
--更新gender值
@pre_gender :=gender
feom scores,
-- 定义变量
(select @total :=0, @pre_gender := NULL) as init
ORDER BY gender,day
3.上面得到的这个表作为新表need,返回gender, day, total
SELECT gender, day, total
FROM (SELECT gender, day,
CASE WHEN @pre_gender = gender THEN @total := @total + score_points
ELSE @total := score_points
END AS total,
@pre_gender := gender
FROM Scores,
(SELECT @total := 0, @pre_gender := NULL) as init
ORDER BY gender, day) AS need
知识点: