首页 > 试题广场 >

获得积分最多的人(一)

[编程题]获得积分最多的人(一)
  • 热度指数:77236 时间限制: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
这题有点抽象,表里的type不一定只有add吧 条件是增加的积分最多也就是add部分的加和最多 但是结果输出的是总积分也就是还要减去reduce部分的 我看了很多答案都考虑的很浅
select
    u.name,
    sum(if(type='add', g.grade_num, -1*g.grade_num)) as grade_sum
from
    grade_info g
join
    user u
on u.id = g.user_id
where u.name in (
    select
        name
    from
        (
            select
                name,
                grade_num,
                type,
                dense_rank() over(order by grade_num_add desc) as rk
            from
                (
                    select
                        u.id,
                        u.name,
                        g.grade_num,
                        g.type,
                        sum(g.grade_num) over(partition by g.user_id) as grade_num_add
                    from
                        grade_info g
                    join user u
                    on u.id = g.user_id
                    where g.type = "add"
            ) as sub
        ) as a
where rk = 1
)
group by 1;

发表于 2025-07-03 17:17:06 回复(0)
借鉴评论区窗口函数代码,如果用limit 1没有考虑并列的情况
select u.name, grade_num
from
    (select user_id,grade_num,rank()over(order by grade_num desc) r
    from   
        (select distinct user_id,sum(grade_num)over(partition by user_id) as grade_num
        from grade_info gi)a)b
left join  user u
on b.user_id =u.id
where r=1


发表于 2025-06-30 13:48:04 回复(0)
题目说了只有一个,直接 limit了
select 
    name,sum(grade_num) as sg
from 
    grade_info
join user on user.id = grade_info.user_id
where 
    type = 'add'
group by name
order by sg DESC 
limit 1;


发表于 2025-05-08 11:01:06 回复(0)
两种方法
一:使用sumover开窗函数,可以分组后计算相应数值的和
select name,sum(grade_num)over(partition by user_id) as grade_sum
from grade_info join user on grade_info.user_id = user.id
order by grade_sum desc
limit 1
二:不用sumover开窗函数,进行表连接
select u.name, g.grade_num
from (
    select user_id, sum(grade_num) grade_num
    from grade_info
    group by user_id
    order by grade_num desc
    limit 1
) g left join user u on g.user_id = u.id




发表于 2025-03-01 10:38:53 回复(0)
#先把各个user_id对应的grade_num的和找到
# with grade as (
#        select user_id,sum(grade_num) as grade_num
#        from grade_info
#        group by user_id
# )


#然后再查找这个表中最大的
select u.name ,max(g.grade_num) as grade_num
from user as u ,(select user_id, sum(grade_num) as grade_num
                 from grade_info 
                 group by user_id) as g 
where u.id=g.user_id
group by u.name 
order by grade_num desc 
limit 0,1

发表于 2024-11-25 16:07:10 回复(0)
有没有大佬帮忙看一下哪里有问题卡在这好久了
select
    name,
    grade_num
from
    (
        select
            a.name as name,
            ROW_NUMBER() over (
                partition by
                    a.name
                order by
                    b.sum_num DESC
            ) as ranked,
            b.sum_num as grade_num
        from
            user a
            left join (
                select
                    user_id,
                    sum(grade_num) as sum_num
                from
                    grade_info
                where
                    type = 'add'
                group by
                    user_id
            ) b on a.id = b.user_id
    ) c
where ranked =1
发表于 2024-10-23 11:05:23 回复(0)
有没有大佬帮忙优化一下
select name,total_num from user u
join(
select g.user_id,sum(grade_num) as total_num from user u
join grade_info g on g.user_id=u.id
group by g.user_id) a on u.id=a.user_id
order by total_num desc
limit 1
发表于 2024-10-03 17:03:13 回复(0)

题目说了保证最高值只有一个,所以可以直接sum+降序排序

select t2.name, sum(t1.grade_num) as cnt
from grade_info t1
left join user t2 on t1.user_id = t2.id 
group by t1.user_id, t2.name
order by sum(t1.grade_num) desc 
limit 1
发表于 2024-08-15 11:11:10 回复(0)
select name, grade_num
from
(
select *, dense_rank() over(order by grade_num desc) as grade_rank
from
(
select name, grade_num
from user as t1
left join
(
select user_id, sum(grade_num) as grade_num 
from grade_info
group by user_id
order by user_id
) as t2
on t1.id=t2.user_id
) as t3
) as t4
where grade_rank=1;

发表于 2024-07-30 00:20:05 回复(0)
select b.name,sum(a.grade_num) over(partition by a.user_id ) num
from grade_info a
join user b on b.id = a.user_id
order by num desc 
limit 1
发表于 2024-07-08 14:41:26 回复(0)
SELECT *
FROM(
    SELECT
        u.name,
        sum(g.grade_num) AS grade_num
    FROM grade_info g
    LEFT JOIN user u 
        ON u.id = g.user_id
    WHERE g.type = 'add'
    GROUP BY u.name
) AS g2
ORDER BY grade_num DESC
LIMIT 1;

发表于 2024-05-07 18:31:47 回复(0)
select name, grade_num from
(select name, grade_num, dense_rank()over(order by grade_num desc) as rk from
(select name, sum(grade_num) as grade_num from
user u right join grade_info gi on u.id=gi.user_id
group by name
order by grade_num desc) as t) as p
where p.rk=1

编辑于 2024-03-25 00:42:54 回复(0)
select u.name,sum(g.grade_num)over(partition by g.user_id) grade_num
from grade_info g left join user u
on g.user_id = u.id
order by grade_num desc
limit 1

编辑于 2024-03-04 14:36:32 回复(0)
select b.name,t.grade_num from
(select user_id,sum(grade_num) grade_num from grade_info
where type='add'
group by user_id
order by grade_num desc
limit 1) t
join user b
on t.user_id=b.id;

编辑于 2024-02-07 14:35:41 回复(0)
select u.name,sum(grade_num) as grade_num
from user u, grade_info g
where u.id = g.user_id
group by u.name
order by grade_num desc
limit 0,1;
发表于 2024-01-23 22:05:48 回复(0)
select bb.name,aa.grade_num from 
(select user_id,sum(grade_num) as grade_num
from grade_info
where type='add'
group by user_id
order by grade_num desc
limit 0,1) aa,user bb
where aa.user_id=bb.id

编辑于 2024-01-03 14:52:54 回复(0)
select
    name,
    grade_num
from
    (
    select
        name,
        grade_num,
        row_number() over(order by grade_num desc) as rk
    from
    (
    select
        u.name,
        sum(grade_num) as grade_num
    from grade_info gi
    left join user u 
    on gi.user_id = u.id
    and gi.type = 'add'
    group by u.name
    ) t0
    group by name
    ) t1 
where rk = 1

好像写复杂了
发表于 2023-11-27 23:06:35 回复(0)
# 请你写一个SQL查找积分增加最高的用户的名字,以及他的总积分是多少(此题数据保证积分最高的用户有且只有1个),以上例子查询结果如下:

with dwd_data as (
select 
user_id,
sum(grade_num) over(partition by user_id )as grade_num
from grade_info where type = 'add'
)


select name,grade_num
from (
select 
t2.name,
grade_num,
row_number () over(order by grade_num desc) as rn
from dwd_data t1 
inner join user t2 on t1.user_id = t2.id
) tt 
where tt.rn =1;

发表于 2023-10-20 17:36:15 回复(0)
with 
t1 as(select
          user_id
          ,sum(grade_num)as grade_num
      from grade_info
      group by user_id
      )

select 
    u.name 
    ,t1.grade_num
from 
    user u 
left join
    t1
on
    u.id = t1.user_id
order by
    grade_num desc
limit 1

发表于 2023-05-26 15:37:03 回复(0)
窗口函数配合子查询嵌套:

第一步:联结两表,取出用户名以及其总积分:
(SELECT
     u.name,
     SUM(gi.grade_num) OVER (PARTITION BY gi.user_id) AS grade_num
 FROM 
     user AS u INNER JOIN grade_info AS gi
         ON u.id = gi.user_id) AS t1

第二步:在上表基础上,取出用户名,总积分以及总积分排名:
SELECT
    name,
    grade_num,
    ROW_NUMBER() OVER (ORDER BY grade_num DESC) AS rk
FROM
    (SELECT
         u.name,
         SUM(gi.grade_num) OVER (PARTITION BY gi.user_id) AS grade_num
     FROM
         user AS u INNER JOIN grade_info AS gi
             ON u.id = gi.user_id) AS t1) AS t2

第三步: 在上表基础上,取出用户名,总积分并用WHERE子句筛选出总积分排名为1的记录(完整代码):
SELECT
    name,
    grade_num
FROM
    (SELECT
        name,
        grade_num,
        ROW_NUMBER() OVER (ORDER BY grade_num DESC) AS rk
    FROM
    (    SELECT
            u.name,
            SUM(gi.grade_num) OVER (PARTITION BY gi.user_id) AS grade_num
        FROM
            user AS u INNER JOIN grade_info AS gi
                ON u.id = gi.user_id) AS t1) AS t2
WHERE rk = 1



发表于 2023-05-16 21:56:09 回复(0)