Как можно было бы эффективно написать запрос, чтобы получить результаты, аналогичные оконным функциям, представленным ниже?
CREATE TABLE student(course varchar2(10), mark number, name varchar2(10));INSERT INTO student VALUES
('Maths', 60, 'Thulile'),
('Maths', 60, 'Pritha'),
('Maths', 70, 'Voitto'),
('Maths', 55, 'Chun'),
('Biology', 60, 'Bilal'),
('Biology', 70, 'Roger');
('Maths', 70, 'Voitto'),
('Maths', 55, 'Chun'),
('Biology', 60, 'Bilal'),
('Biology', 70, 'Roger');
SELECT
RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank_,
DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank_,
ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_number_,
course, mark, name
FROM student ORDER BY course, mark DESC;
RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank_,
DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank_,
ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_number_,
course, mark, name
FROM student ORDER BY course, mark DESC;
rank_ | dense_rank_ | row_number_ | course | mark | name |
---|---|---|---|---|---|
1 | 1 | 1 | Biology | 70 | Roger |
2 | 2 | 2 | Biology | 60 | Bilal |
1 | 1 | 1 | Maths | 70 | Voitto |
2 | 2 | 2 | Maths | 60 | Thulile |
2 | 2 | 3 | Maths | 60 | Pritha |
4 | 3 | 4 | Maths | 55 | Chun |
Решение:
with stds as (select course, mark, name
,(select count(mark) from students t where t.course = e.course and t.mark = e.mark) as sign
,(select count(distinct mark)
from students t where t.course = e.course and
t.mark >= e.mark) as dense_rank_
,(select count(1)
,(select count(1)
from students e)
select
case when sign > 1 then dense_rank_ else row_number_ end as rank_
,dense_rank_
,row_number_
select
case when sign > 1 then dense_rank_ else row_number_ end as rank_
,dense_rank_
,row_number_
,course, mark, name
from stds
order by course, mark desc, name desc;
from stds
order by course, mark desc, name desc;