首页 > 试题广场 >

获得积分最多的人(一)

[编程题]获得积分最多的人(一)
  • 热度指数:75289 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
牛客每天有很多用户刷题,发帖,点赞,点踩等等,这些都会记录相应的积分。
有一个用户表(user),简况如下:
id name
1 tm
2 wwy
3 zk
4 qq
5 lm

还有一个积分表(grade_info),简况如下:
user_id grade_num type
1 3 add
2 3 add
1 1 add
3 3 add
4 3 add
5 3 add
第1行表示,user_id为1的用户积分增加了3分。
第2行表示,user_id为2的用户积分增加了3分。
第3行表示,user_id为1的用户积分又增加了1分。
.......
最后1行表示,user_id为5的用户积分增加了3分。

请你写一个SQL查找积分增加最高的用户的名字,以及他的总积分是多少(此题数据保证积分最高的用户有且只有1个),以上例子查询结果如下:
name grade_num
tm 4
解释:
user_id为1的总计加了4分,其他的都是3分,user_id为1的name为tm
输出tm|4
示例1

输入

drop table if exists user;
drop table if exists grade_info;

CREATE TABLE user (
id  int(4) NOT NULL,
name varchar(32) NOT NULL
);

CREATE TABLE grade_info (
user_id  int(4) NOT NULL,
grade_num int(4) NOT NULL,
type varchar(32) NOT NULL
);

INSERT INTO user VALUES
(1,'tm'),
(2,'wwy'),
(3,'zk'),
(4,'qq'),
(5,'lm');

INSERT INTO grade_info VALUES
(1,3,'add'),
(2,3,'add'),
(1,1,'add'),
(3,3,'add'),
(4,3,'add'),
(5,3,'add');

输出

tm|4
写出了非常麻烦的sql语句emmmm
## 使用limit
select name, grade_sum
from (
    select user_id, sum(grade_num) grade_sum
    from grade_info
    group by user_id
)T
join user T2 on T2.id = T.user_id
order by grade_sum desc
limit 1

## 不使用limit
select name, grade_sum
from (
    select user_id, sum(grade_num) grade_sum
    from grade_info
    group by user_id
)T
join user T2 on T2.id = T.user_id
where grade_sum = (
    select max(grade_sum) 
    from (
        select user_id, sum(grade_num) grade_sum
        from grade_info
        group by user_id
    ) A
)


发表于 2021-04-11 12:32:16 回复(0)

with t as(
select user_id,sum(grade_num) gn 
    from grade_info
GROUP BY user_id )
select u.name,max(t.gn) from t
JOIN user u 
on t.user_id =u.id
GROUP BY u.id,u.name
ORDER BY t.gn desc
LIMIT 1
;

发表于 2022-01-26 10:58:28 回复(0)
直接SUM聚合,再GROUP BY 按u.id分组排列多香,不一定非得用子查询啊
SELECT 
    u.name,
    SUM(grade_num) AS grade_sum
FROM user u
JOIN grade_info g
ON u.id =g.user_id
GROUP BY u.id
order by grade_sum desc
limit 0,1;
发表于 2021-04-30 19:09:28 回复(8)
想来想去也就想到limit一个解法:(倒序排列,取第一个即为最大分数)
select name,s grade_sum
from
(select name,user_id,sum(grade_num) s
from user,grade_info
where id = user_id
group by user_id) a
order by s desc
limit 0,1
发表于 2021-03-30 16:16:00 回复(7)
这个题描述的。。。。万一type有minus不得完蛋
发表于 2022-02-27 22:07:28 回复(0)
为什么不能用max函数呢?
发表于 2021-08-08 14:47:46 回复(9)
先按user_id分组统计和,如下结果:
select user_id,sum(grade_num) as grade_sum from grade_info group by user_id order by grade_sum desc;

因为是最大的只有1个,所以使用limit 1 再联立user表就可以得到结果:
select user.name,t.grade_sum from
(select user_id,sum(grade_num) as grade_sum from grade_info group by user_id order by grade_sum desc limit 1) t
join user
on t.user_id=user.id



也可以用前面学过的sum ()over来解决:
select user.name,t.grade_sum from
(select user_id, sum(grade_num)over(partition by user_id ) grade_sum from grade_info order by grade_sum desc limit 1) t
join user
on t.user_id=user.id


编辑于 2021-03-30 15:27:46 回复(2)
# 解题思路
1.善用开窗函数, 按照user_id分组,然后求和积分,并且按照求和的结果进行求最大值
2.join用户表,取出name
select b.name, sl
from (
    select user_id, sum(grade_num) as sl, max(sum(grade_num)) over() as t_sl
    from grade_info
    group by user_id) a 
join user b on a.user_id = b.id
where sl = t_sl


发表于 2022-04-21 14:15:38 回复(0)
select  u.name
, sum(g.grade_num) as grade

from grade_info g
left join user u on g.user_id = u.id

group by u.name
Order by 2 desc
limit 1


名字和id是对应的,所以不需要再选id,直接group by name就行了。
题目明确说了是一个最高分,感觉明显是为了让用limit。
编辑于 2021-04-29 09:25:02 回复(3)
select n.name,m
from (select u.name, m,rank()over(order by m desc) s
from user u left join (select user_id,sum(grade_num) m
from grade_info
group by user_id) g
on u.id=g.user_id) n
where n.s=1
发表于 2022-07-18 21:54:35 回复(0)
select 
name,sum(grade_num) as grade_num
from grade_info gi
join user u on gi.user_id=u.id
group by name
order by grade_num desc
limit 1
默认前提:所有的积分都是加(add)且积分最高的用户有且只有1个
发表于 2022-06-30 15:22:07 回复(0)
SELECT
u.name,
sum(g.grade_num) as total
from user u
JOIn grade_info g
on g.user_id=u.id
group by u.name
order by total DESC
LIMIT 1

为啥都那么麻烦,这个不简单吗
发表于 2022-02-28 18:34:34 回复(0)
法一:
select name,sum(grade_num) 
from grade_info g
join user u  on u.id = g.user_id 
group by user_id
order by sum(grade_num) DESC
LIMIT 1

法二:
select name,sum(grade_num)
from grade_info g
join user u  on u.id = g.user_id 
group by user_id
having sum(grade_num) = 
(
 select MAX(sgn) from
 (select SUM(grade_num) sgn from grade_info group by user_id) s
)
【注意】
having后面条件写成
 select MAX(sgn) from
 (select SUM(grade_num) sgn from grade_info group by user_id) s
可以;
写成
select MAX(SUM(grade_num))from grade_info group by user_id)
不行。应该是因为先group by 分组再在每组中找 MAX(SUM(grade_num)),这样找不到。




发表于 2021-10-19 20:54:54 回复(5)
分组、求和、降序排序、取第一条,最后来个表连接,完美!
select u.name,t.grade_sum from user u
join (
    select user_id, sum(grade_num) grade_sum from grade_info 
    group by user_id 
    order by grade_sum desc 
    limit 1
) t 
on u.id=t.user_id;


发表于 2021-04-01 11:28:40 回复(3)
sql入门小白,哪位大神可以帮忙解答一下这个运行代码出错的地方呀~感谢
select u.name, g.grade
from
(select user_id,grade_num
from grade_info
group by user_id having sum(grade_num)
order by user_id limit 1)g
join
user as u
on g.user_id = u.id
发表于 2024-06-28 11:17:57 回复(1)
select name,grade_num from
(select name,sum(grade_num) grade_num
from user u
join
grade_info g
on u.id=g.user_id
where type='add'
group by name
)t
order by grade_num desc
limit 1;

发表于 2024-04-12 10:08:11 回复(0)
如果积分最多的不止一个,怎样写比较高效?
发表于 2023-06-30 14:55:05 回复(0)
#输出最值的时候,一般有三种方法:聚合函数、窗口函数、limit
select name,grade_num as grade_num
from
(select user_id,sum(grade_num) as grade_num
from grade_info group by user_id) as gi 
inner join user as u 
on gi.user_id=u.id 
order by grade_num desc 
limit 1;

发表于 2023-03-07 10:07:35 回复(0)
select u.name,sum(g.grade_num) from user as u 
join grade_info as g on u.id=g.user_id
group by name
limit 0,1
发表于 2022-08-08 22:17:06 回复(0)
SELECT name,MAX(a.gn) AS grade_sum
FROM
(SELECT user_id,SUM(CASE WHEN type='add'THEN grade_num ELSE (-1)*grade_num END) AS gn
FROM grade_info 
GROUP BY user_id) AS a
INNER JOIN user AS u 
ON a.user_id=u.id;
发表于 2021-12-21 23:30:19 回复(0)