воскресенье, 8 января 2023 г.

Не используя оконные функции RANK, DENSE_RANK, ROW_NUMBER

Как можно было бы эффективно написать запрос, чтобы получить результаты, аналогичные оконным функциям, представленным ниже?

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');

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_   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) 
       from students t where t.course = e.course and t.mark||t.name >= e.mark||e.name) as row_number_
   from students e)
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;




Комментариев нет:

Отправить комментарий