首页 > 试题广场 >

考试分数(三)

[编程题]考试分数(三)
  • 热度指数:126686 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
牛客每次举办企业笔试的时候,企业一般都会有不同的语言岗位,比如C++工程师,JAVA工程师,Python工程师,每个用户笔试完有不同的分数,现在有一个分数(grade)表简化如下:
id language_id score
1 1 12000
2 1 13000
3 2 11000
4 2 10000
5 3 11000
6 1 11000
7 2 11000
第1行表示用户id为1的选择了language_id为1岗位的最后考试完的分数为12000,
....
第7行表示用户id为7的选择了language_id为2岗位的最后考试完的分数为11000,

不同的语言岗位(language)表简化如下:
id name
1 C++
2 JAVA
3 Python

请你找出每个岗位分数排名前2名的用户,得到的结果先按照language的name升序排序,再按照积分降序排序,最后按照grade的id升序排序,得到结果如下:
id name score
2 C++
13000
1 C++
12000
3 JAVA
11000
7 JAVA
11000
4 JAVA
10000
5 Python
11000
示例1

输入

drop table if exists grade;
drop table if exists language;
CREATE TABLE `grade` (
`id` int(4) NOT NULL,
`language_id` int(4) NOT NULL,
`score` int(4) NOT NULL,
PRIMARY KEY (`id`));

CREATE TABLE `language` (
`id` int(4) NOT NULL,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`id`));

INSERT INTO grade VALUES
(1,1,12000),
(2,1,13000),
(3,2,11000),
(4,2,10000),
(5,3,11000),
(6,1,11000),
(7,2,11000);

INSERT INTO language VALUES
(1,'C++'),
(2,'JAVA'),
(3,'Python');

输出

2|C++|13000
1|C++|12000
3|JAVA|11000
7|JAVA|11000
4|JAVA|10000
5|Python|11000
select g1.id,name,score from
(select *,dense_rank() over (partition by language_id order by score desc) as r
from grade) as g1,language as l
where r<=2 and l.id=g1.language_id
order by name,score desc,g1.id;
发表于 2024-10-21 11:53:58 回复(0)
WITH t as (SELECT
    g.id,
    l.name,
    g.score,
    dense_rank() over (PARTITION by l.NAME ORDER BY g.score DESC) AS ranking
FROM
    grade g
    INNER JOIN language l ON g.language_id = l.id )
    SELECT t.id,t.name,t.score FROM t where t.ranking<3 ORDER BY t.name ASC,t.score DESC
   
   
发表于 2024-10-10 10:25:14 回复(0)
SELECT re.id,name,score
FROM
(
    SELECT id,language_id,score,dense_rank()over(partition by language_id order by score desc) 排序
    FROM grade
) re
JOIN language ON re.language_id=language.id
WHERE re.排序<=2
order by name,score desc
发表于 2024-09-19 22:36:06 回复(0)
select t.id, name, score
from
(
    (
select
*,
dense_rank() over(partition by language_id order by score desc) as t_rank
from grade
    ) t
left join language
on t.language_id = language.id
)
where t_rank <= 2
order by name, score desc, t.id


发表于 2024-09-13 16:33:19 回复(0)

可以使用窗口函数解决
注意窗口函数rank(), dense_rank() 的不同之处

select t1.id, t2.name, t1.score
from (
    select *
    -- 注意此处用dense_rank() 排序,同分即同名次
    , dense_rank() over(partition by language_id order by score desc) as rn
    from grade 
) t1 left join language t2 on t1.language_id = t2.id 
where t1.rn <= 2
order by t2.name asc, t1.score desc, t1.id asc
发表于 2024-08-13 15:41:03 回复(0)
select s.id,s.name,s.score
from
(select t.id,t.name,t.score,
dense_rank() over(partition by name order by score desc) as rn 
from (select g.id,name,score
from grade g
left join language l 
on g.language_id=l.id) as t) as s
where s.rn in(1,2)
order by s.name,s.score desc,s.id;

发表于 2024-08-01 15:35:34 回复(0)
select
   a.id,name,score
from
    grade a,
    language b
where
    a.language_id = b.id
    and  (a.score = (
        select
            max(score) as score
        from
            grade
        where
            language_id = a.language_id
    )
   &nbs***bsp;
    a.score = (
        select
            max(score) as score
        from
            grade
        where
            score < (
                select
                    max(score) as score
                from
                    grade
                where
                    language_id = a.language_id
            )
            and language_id = a.language_id
    )
    )
    order by name,score desc
发表于 2024-07-17 17:46:47 回复(0)
select
    t.id,
    t.name,
    t.score 
from (
    select
        g.id,
        l.name,
        g.score,
        dense_rank() over (partition by l.name order by g.score desc) rk
    from grade g join language l
    on g.language_id=l.id
) t
where t.rk=1 or t.rk=2
order by t.name,t.score desc,t.id
发表于 2024-06-10 21:40:26 回复(0)
SELECT
    id,
    name,
    score
FROM(
    SELECT
    g.id,
    l.name,
    g.score,
    DENSE_RANK()OVER(partition by l.name ORDER BY g.score DESC ) AS rank_id
    FROM grade g
    JOIN language l 
        ON g.language_id = l.id
) AS grade_language
WHERE rank_id IN ('1','2');

发表于 2024-04-11 11:52:46 回复(0)
select a.id,a.name,a.score 
from
(select g.id as id,name,score,dense_rank() over(partition by name order by score desc) as rk from grade as g
inner join language as l on g.language_id=l.id) as a #窗口先排序
where rk<3 #选择排序在前两名的
order by a.name,a.score desc;

编辑于 2024-01-13 16:45:52 回复(0)
经常忘记最后order by,太不应该了
select aa.id ,bb.name,aa.smallscore score
from 
(select distinct a.language_id,a.id,a.score smallscore,b.score largescore
from grade a
left join grade b
on a.language_id=b.language_id
and a.score<b.score
order by a.language_id,a.score desc
) aa ,language bb where aa.language_id=bb.id
group by aa.language_id,aa.id having count(aa.id)<2
order by bb.name,score desc,aa.id


编辑于 2023-12-29 16:24:16 回复(0)
请问一下大家
想要把grade和language内连接后分组查询
为什么加入group by语句后就报错了呢?

具体代码如下:
select *
from grade g
join language l on g.language_id=l.id
group by g.language_id


发表于 2023-11-12 11:42:14 回复(0)
# 请你找出每个岗位分数排名前2名的用户,得到的结果先按照language的name升序排序,再按照积分降序排序,最后按照grade的id升序排序,得到结果如下:

-- 注意:本题考查排名前2名,dense_rank 排序;

with dwd_data as (
select id,language_id,score,
 dense_rank()over(partition by language_id order by score desc) as rn_score
 from grade
)

select 
 t1.id,t2.name,t1.score
from dwd_data t1 
inner join language t2 on t1.language_id = t2.id
where t1.rn_score<=2
order by 2 asc,3 desc,1 asc;

发表于 2023-09-25 11:27:06 回复(0)
select 
    t2.id,
    t3.name,
    t2.score
from (
    select
        *,
        dense_rank() over(partition by t1.language_id order by t1.score desc) as rk
    from
        grade t1
) t2
left join
    language t3
on 
    t2.language_id = t3.id
where
    t2.rk <= 2
order by 
    t3.name asc,
    t2.score desc

发表于 2023-09-16 16:52:54 回复(0)
select
    t.id,
    t.name,
    t.score
from
    (
        select
            g.id,
            l.name,
            g.score,
            dense_rank() over (
                partition by
                    g.language_id
                order by
                    g.score desc
            ) as ranking
        from
            grade g
            inner join language l on g.language_id = l.id
    ) t
where
    t.ranking < 3
order by
    t.name asc,
    t.score desc,
    t.id asc
发表于 2023-09-10 00:08:11 回复(0)
每个岗位分数排名前2名的用户,就应该用RANK 呀,答案明显是DENSE_RANK排序的,同样是取前2名,JAVA就可以有3个人了?
发表于 2023-06-06 16:31:00 回复(0)
select
    o1.id,
    o1.name,
    o1.score
from
    (
        select
            t1.id,
            t2.name,
            t1.score,
            dense_rank() over (
                partition by
                    t2.name
                order by
                    t1.score desc
            ) ranking
        from
            grade t1
            inner join language t2 on t1.language_id = t2.id
    ) o1
where
    o1.ranking <= 2
order by
    o1.name asc,
    o1.score desc,
    o1.id asc;

发表于 2023-05-31 12:04:38 回复(0)
with tmp1 as( # 2表联结
    select g.id,g.score,l.name
    from grade g
    inner join language l
    on g.language_id=l.id
)
,
score_list as( #拿到去重后的分数列表
    select distinct score,name from tmp1
)
,
score_rank as( # 得到不同岗位分数对应的排名
    select *,row_number() over(partition by name order by score desc ) as rn
    from score_list
)

# tmp1和score_rank两表联结
select tmp1.id,tmp1.name,tmp1.score 
from score_rank s inner join tmp1 
on tmp1.name=s.name and tmp1.score=s.score
where rn<=2
order by name asc,score desc,id asc

发表于 2023-01-26 16:15:55 回复(0)
select t1.id, name, score
from(
select id, language_id, score, dense_rank() over (partition by language_id order by score desc) as rnk
from grade) t1
left join language t2
on t1.language_id = t2.id
where t1.rnk <= 2
order by name, score desc, t1.id;

发表于 2023-01-08 21:33:02 回复(0)
select a1.id,name,score
from
(select id,language_id,score,dense_rank()over(partition by language_id order by score desc) as rn
from grade) a1
join language l
on a1.language_id = l.id
where a1.rn <= 2
order by name asc,score desc, a1.id asc
发表于 2023-01-07 16:31:02 回复(0)