首页 > 试题广场 >

考试分数(四)

[编程题]考试分数(四)
  • 热度指数:68309 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

牛客每次考试完,都会有一个成绩表(grade),如下:

id job score
1 C++
11001
2 C++
11000
3 C++
9000
4 JAVA
12000
5 JAVA
13000
6 B
12000
7
B
11000
8 B
9999

第1行表示用户id为1的用户选择了C++岗位并且考了11001分

。。。

第8行表示用户id为8的用户选择了B语言岗位并且考了9999分

请你写一个sql语句查询各个岗位分数升序排列之后的中位数位置的范围,并且按job升序排序,结果如下:

job start end
B 2 2
C++ 2 2
Java 1 2

解释:

第1行表示C++岗位的中位数位置范围为[2,2],也就是2。因为C++岗位总共3个人,是奇数,所以中位数位置为2是正确的(即位置为2的10000是中位数)

第2行表示Java岗位的中位数位置范围为[1,2]。因为Java岗位总共2个人,是偶数,所以要知道中位数,需要知道2个位置的数字,而因为只有2个人,所以中位数位置为[1,2]是正确的(即需要知道位置为1的12000与位置为2的13000才能计算出中位数为12500)

第3行表示前端岗位的中位数位置范围为[2,2],也就是2。因为B语言岗位总共3个人,是奇数,所以中位数位置为2是正确的(即位置为2的11000是中位数)

(注意: sqlite 1/2得到的不是0.5,得到的是0,只有1*1.0/2才会得到0.5,sqlite四舍五入的函数为round,sqlite不支持floor函数,支持cast(x as integer) 函数,不支持if函数,支持case when ...then ...else ..end函数)

示例1

输入

drop table if exists grade;
CREATE TABLE  grade(
`id` int(4) NOT NULL,
`job` varchar(32) NOT NULL,
`score` int(10) NOT NULL,
PRIMARY KEY (`id`));

INSERT INTO grade VALUES
(1,'C++',11001),
(2,'C++',10000),
(3,'C++',9000),
(4,'Java',12000),
(5,'Java',13000),
(6,'B',12000),
(7,'B',11000),
(8,'B',9999);

输出

B|2|2
C++|2|2
Java|1|2
select distinct(job)
,case when cnt%2 <> 0 then round(cnt/2,0) else round(cnt/2,0) end start
,case when cnt%2 <> 0 then round(cnt/2,0) else round(cnt/2+1,0) end end
from (
    select job
    ,count(score) cnt
    from grade
    group by job
) t2
order by job asc;

发表于 2021-10-31 10:42:22 回复(0)
what are you doing 你们在做什么
难道不是  总数/2 (总数+1)除以2 吗

select a.job, round(count(a.id)/2), round((count(a.id)+1)/2)
from grade a
group by a.job
order by job


发表于 2020-11-12 01:09:49 回复(32)
Start部分向下取整,End部分向上取整
select job,floor((count(job)+1)/2) as start,ceiling((count(job)+1)/2) as end
from grade
group by job
order by job


发表于 2021-04-06 14:16:37 回复(1)
SELECT 
job,
CASE WHEN total%2=0 THEN total/2 ELSE (total+1)/2 END AS `start`,
CASE WHEN total%2=0 THEN total/2+1 ELSE (total+1)/2 END AS `end`
FROM
(SELECT job,COUNT(1) AS total
FROM grade
GROUP BY job)t;
发表于 2020-09-28 15:04:28 回复(3)
SELECT job,
case when total%2 = 0 then total/2 else (total+1)/2 end as 'start',
case when total%2 = 0 then total/2 +1 else (total+1)/2 end as 'end'
FROM
(
SELECT job, COUNT(*) as total
FROM grade
GROUP BY job
)
发表于 2020-10-28 00:08:50 回复(0)
SQLite:
select job,(count(*)+1)/2 as start,count(*)/2+1 as end
from grade
group by job
order by job;

MYSQL:
select job,
    floor((count(*)+1)/2) as start,
    floor(count(*)/2+1) as end
from grade  
group by job 
order by job;
发表于 2020-12-05 17:39:30 回复(1)
首先肯定是根据不同的岗位来的,故总体架构为:
select xxx
from grade 
group by job order by job;
因为只是求中位数的位置,故不需要排序,也不需要知道中位数是多少。
假设1个岗位人数总数为N,那么不管是奇数还是偶数,起始位置一定是N/2,如果是奇数,那么终止位置也是N/2,如果是偶数,终止位置就是N/2+1,所以后面的+1判断是不是偶数就行了
select job, cast((count(id)+1)/2 AS INTEGER) as 'start' , 
(cast((count(id)+1)/2 AS INTEGER)+(case when count(id)%2=1 then 0 else 1 end)) as 'end' --终止位置+是不是偶数(是不是+1)
from grade 
group by job order by job;



mysql解法:
SELECT job,FLOOR((COUNT(*)+1)/2) AS `start`,FLOOR((COUNT(*)+1)/2)+if(COUNT(*) % 2=1,0,1) AS `end` 
from grade  
GROUP BY job 
order by job;
编辑于 2020-11-05 16:38:31 回复(1)
思路:
求中位数,只需要知道每个岗位的总数,用聚合函数count;得出总数后,再分奇/偶讨论中位数;
偶数:start=count/2,end=count/2+1;
奇数:start=count/2,得到的会是x.5,用round取整;end同理

代码:
select a.job
,case when(a.c%2=0) then round((a.c/2),0) else (round(a.c/2,0)) end as start
,case when(a.c%2=0) then round((a.c/2+1),0) else (round(a.c/2,0)) end as end
from (
    select job,count(*) as c
    from grade
    group by job
) a
order by a.job asc




发表于 2021-10-06 12:33:42 回复(0)
#中位数的特征:
#当个数为偶数时,中位数的起始位置等于个数/2,结束位置等于个数/2+1
#当个数为奇数时,中位数的起始位置等于向上取整(个数/2),结束位置等于向上取整(个数/2)
#用除以2的余数是否为0来判断奇偶,%2=0
#记得取整数,本题用ceiling函数向上取整(返回不小于该数的最小整数值)或round(数,0)四舍五入取整都可以
select job
        ,case when count(score)%2=0 then ceiling(count(score)/2) else ceiling(count(score)/2)
        end as start1
        ,case when count(score)%2=0 then ceiling(count(score)/2+1) else ceiling(count(score)/2)
        end as end1
from grade
group by job
order by job;


发表于 2021-01-26 15:12:28 回复(0)
#解题思路  利用mysql向上取整ceil(其实用round也可以),当数量为偶数,则end+1,数量为奇数,就是end和start都一样
例如:2个数的中位数是1,2,是用2/2, 2/2+1
3个数的中位数是2,2,是用ceil(3/2), ceil(3/2)
select job,  ceil(count(*)/2) as `start`,
(case when count(*)%2=0 then ceil(count(*)/2)+1 else ceil(count(*)/2) end) as `end`
from grade
group by job
order by job


发表于 2022-04-19 14:53:54 回复(0)
select 
job,
ceil(count(*)/2) as start,
ceil((count(*)+1)/2) as end
from grade
group by job
order by job
发表于 2021-11-22 13:46:28 回复(0)
select job, round(count(id)/2), round((count(id)+1)/2)
from grade 
group by job
order by job;

发表于 2021-08-31 15:30:45 回复(0)
简单的问题复杂化,不愧是我,向第一大佬膜拜
select job, 
( case max(rownum)%2
 when 1
 then round((max(rownum)*1.0/2 + 0.5))
 else round((max(rownum)*1.0/2))
 end
) start, 
( case max(rownum)%2
 when 1
 then round((max(rownum)*1.0/2 + 0.5))
 else round((max(rownum)*1.0/2 + 1))
 end
) end
from (
    select job, score, row_number() over (partition by job order by score desc) rownum
    from grade
) T
group by job
order by job


发表于 2021-03-31 22:06:21 回复(0)
select job, 
round((case  when count(*) % 2 = 0 then count(*)/2 else (count(*) + 1)/2 end),0) as start,
round((case  when count(*) % 2 = 0 then count(*)/2+1 else (count(*) + 1)/2 end),0) as end
from grade
group by job
order by job

case when解法
发表于 2021-02-23 14:43:52 回复(1)
select job,floor((count(id)+1)/2) as 'start',ceil((count(id)+1)/2) as 'end'
from grade 
group by job
order by job asc


如果是奇数个:那么 中位数的位置是(count(id)+1)/2
如果是偶数个:那么中位数的位置是floor((count(id)+1)/2) 和 ceil((count(id)+1)/2)

编辑于 2020-11-25 10:29:14 回复(0)
select job, 
    case when count(score)*1.0/2=count(score)/2*1.0 then count(score)/2
    else count(score)/2+1 end as start,
    case when count(score)*1.0/2=count(score)/2*1.0 then count(score)/2+1
    else count(score)/2+1 end as end
from grade group by job order by job;

发表于 2020-10-28 23:40:04 回复(0)
不知道怎么求中位数,写的狗屎
select distinct job, case when s % 2 = 1 then round((min(dk) over(partition by job) + max(dk) over(partition by job))/2,0)
else round((min(dk) over(partition by job) + max(dk) over(partition by job))/2, 0) - 1 end,
case when s % 2 = 1 then round((min(dk) over(partition by job) + max(dk) over(partition by job))/2,0) 
else round((min(dk) over(partition by job) + max(dk) over(partition by job))/2, 0) end
from (
    select id, job, score, dense_rank() over(partition by job order by score desc) dk
    ,sum(1) over(partition by job) s
    from grade
) a 

编辑于 2024-01-05 15:57:40 回复(0)
select job,
round(max(rk)/2) start,
round(max(rk+1)/2) end from
(select id,job,rank() over (partition by job order by score desc) rk from grade)a
group by job
发表于 2023-08-12 02:01:06 回复(0)
# 请你写一个sql语句查询各个岗位分数升序排列之后的中位数位置的范围,并且按job升序排序

with t1 as(
    select job,count(*) as  cnt
    from grade
    group by job
)

select job,ceil(cnt/2) as start,ceil((cnt+1)/2) as end
from  t1
order by job asc

发表于 2023-03-24 09:29:26 回复(0)
select distinct job,round(num/2) as start,round((num+1)/2) as end
from (
    select job,
    count(job) over(partition by job) as num
    from grade
)t
order by job;


发表于 2023-01-06 15:05:51 回复(0)