如何从 table 中提取第二高的行
How to extract second highest row from a table
我有四个 tables :
- 批处理(batch_id, batch_start_date, batch_strength, course_id)
- 课程([=35=], course_name, course_category, course_fees, course_duration)
- 注册人数(batch_id, student_id, enrollment_date)
- 学生(student_id, student_name, student_mail, student_date_of_birth, student_city, student_phone, student_qualification)
现在根据问题我必须显示收入第二高的课程名称
根据上面的问题,这里是我的解决方案
select c.course_name, c.course_fees*count(c.course_name) Total_Revenue
from course c join(batch b join enrollment e
on b.batch_id=e.batch_id)
on c.course_id=b.course_id
group by c.course_name, c.course_fees
order by Total_Revenue desc ;
现在的问题是我无法从上述代码的结果 table 中提取第二行。如何从上面的结果 table 中提取第二行?(感谢特定于 Oracle 11g 的答案)
使用row_number()
:
select *
from (select c.course_name, c.course_fees*count(c.course_name) as Total_Revenue,
row_number() over (order by c.course_fees*count(c.course_name)) as seqnum
from batch b join
enrollment e
on b.batch_id = e.batch_id join
course c
on c.course_id=b.course_id
group by c.course_name, c.course_fees
) bec
where seqnum = 2;
如果您能获得并列第一但仍想获得第二名,请使用 dense_rank()
而不是 row_number()
。
您还可以创建自己的聚合函数。 Oracle docs 提到的函数SecondMax 为例。但是如果有一个合适的索引,那么 row_numer 函数可能会给出更好的执行计划。
Non-analytic 解决方案只是为了好玩:
with r as (
select min(c.course_name) as course_name, min(c.course_fees) * count(*) as revenue
from
course c
inner join batch b on b.course_id = c.course_id
inner join enrollment e on e.batch_id = b.batch_id
group by c.course_id
)
select course_name, revenue
from r
where revenue = (select max(revenue) from r where revenue < (select max(revenue) from r))
这会处理平局(第一和第二)。我也很谨慎,假设您真的打算按 course_id
分组。这看起来更像是一个 class 练习,所以我不希望有任何复杂的事情,比如历史费用信息或类似的事情。
编辑
根据您在下面的评论,听起来您可能有多个名称相同但费用不同的课程。我怀疑您的原始查询无法正常工作,因为您也在 course_fees
.
上分组
请注意下面的更改使用了 course_name
上的分组和 course_fees
上的求和:
with r as (
select course_name, sum(c.course_fees) as revenue
from
course c
inner join batch b on b.course_id = c.course_id
inner join enrollment e on e.batch_id = b.batch_id
group by c.course_name
)
select course_name, revenue
from r
where revenue = (select max(revenue) from r where revenue < (select max(revenue) from r))
我有四个 tables :
- 批处理(batch_id, batch_start_date, batch_strength, course_id)
- 课程([=35=], course_name, course_category, course_fees, course_duration)
- 注册人数(batch_id, student_id, enrollment_date)
- 学生(student_id, student_name, student_mail, student_date_of_birth, student_city, student_phone, student_qualification)
现在根据问题我必须显示收入第二高的课程名称
根据上面的问题,这里是我的解决方案
select c.course_name, c.course_fees*count(c.course_name) Total_Revenue
from course c join(batch b join enrollment e
on b.batch_id=e.batch_id)
on c.course_id=b.course_id
group by c.course_name, c.course_fees
order by Total_Revenue desc ;
现在的问题是我无法从上述代码的结果 table 中提取第二行。如何从上面的结果 table 中提取第二行?(感谢特定于 Oracle 11g 的答案)
使用row_number()
:
select *
from (select c.course_name, c.course_fees*count(c.course_name) as Total_Revenue,
row_number() over (order by c.course_fees*count(c.course_name)) as seqnum
from batch b join
enrollment e
on b.batch_id = e.batch_id join
course c
on c.course_id=b.course_id
group by c.course_name, c.course_fees
) bec
where seqnum = 2;
如果您能获得并列第一但仍想获得第二名,请使用 dense_rank()
而不是 row_number()
。
您还可以创建自己的聚合函数。 Oracle docs 提到的函数SecondMax 为例。但是如果有一个合适的索引,那么 row_numer 函数可能会给出更好的执行计划。
Non-analytic 解决方案只是为了好玩:
with r as (
select min(c.course_name) as course_name, min(c.course_fees) * count(*) as revenue
from
course c
inner join batch b on b.course_id = c.course_id
inner join enrollment e on e.batch_id = b.batch_id
group by c.course_id
)
select course_name, revenue
from r
where revenue = (select max(revenue) from r where revenue < (select max(revenue) from r))
这会处理平局(第一和第二)。我也很谨慎,假设您真的打算按 course_id
分组。这看起来更像是一个 class 练习,所以我不希望有任何复杂的事情,比如历史费用信息或类似的事情。
编辑
根据您在下面的评论,听起来您可能有多个名称相同但费用不同的课程。我怀疑您的原始查询无法正常工作,因为您也在 course_fees
.
请注意下面的更改使用了 course_name
上的分组和 course_fees
上的求和:
with r as (
select course_name, sum(c.course_fees) as revenue
from
course c
inner join batch b on b.course_id = c.course_id
inner join enrollment e on e.batch_id = b.batch_id
group by c.course_name
)
select course_name, revenue
from r
where revenue = (select max(revenue) from r where revenue < (select max(revenue) from r))