Это новый вопрос, добавленный Hackerrank для сертификации SQL продвинутого уровня. Я никак не мог ее решить. Кто-нибудь может помочь?
Было несколько конкурсов, в которых каждый участник делал определенное количество попыток. Попытка с наибольшим количеством очков считается единственной. Напишите запрос, чтобы составить список участников, попавших в тройку лучших по каждому конкурсу. Если несколько участников имеют одинаковое количество очков в каждом соревновании, они занимают одинаковое место.
Сообщить event_id, имя (имена) ранга 1, имя (имена) ранга 2, имя (имена) ранга 3. Заказать конкурс по event_id. Имена, имеющие один и тот же ранг, должны быть расположены в алфавитном порядке и разделены запятой.
Упорядочить отчет по event_id
@chegancasb Честно говоря, я пытался решить вопрос, но он настолько сбивает с толку, что я даже не мог начать думать об этом. Я не очень разбираюсь в рангах в sql
Пожалуйста, не ссылайтесь на изображения — разместите всю необходимую информацию непосредственно в своем вопросе, желательно в виде редактируемого текста. Кроме того, разве тот факт, что вы нашли это «настолько запутанным, что я даже не мог начать думать об этом», не означает, что вы не готовы пройти эту сертификацию и вам нужно получить больше опыта, а не просить кого-то еще решить это для вас?
@NickW Я прошел тест, но не смог решить эту проблему, поэтому мне нужно было подсказать, как ее решить. Извините, я буду иметь в виду, что не буду размещать изображения.
Взгляните на DENSE_RANK(). Помимо разделения (которое является группировкой) и упорядочения (например, сначала наивысший балл), DENSE_RANK помещает все те, у кого одинаковый балл, в одну и ту же позицию, поэтому вы можете получить ранжирование 1, 2, 2, 3, 3, 3, 4 в каждой категории группируются.
@SchmitzIT это вопрос, какой скриншот схемы, спасибо
@DRapp, не могли бы вы подсказать, как написать запрос для лучшего понимания? Спасибо.
@RuchiSharma, готово.
@DRapp большое спасибо за краткое объяснение. Это действительно помогает :)
Ниже приведены некоторые примеры данных для вашего сценария. Таблица участников и предпринятых попыток. Сделал попытки каждого человека на своей линии, чтобы вы могли видеть очевидные разные попытки каждого человека.
create table contestants
( id int identity(1,1) not null,
personName nvarchar(10) )
insert into contestants ( personName )
values ( 'Bill' ), ('Mary'), ('Jane' ), ('Mark')
create table attempts
( id int identity(1,1) not null,
contestantid int not null,
score int not null )
insert into attempts ( contestantid, score )
values
( 1, 72 ), ( 1, 88 ), (1, 81 ),
( 2, 83 ), ( 2, 88 ), (2, 79), (2,86),
( 3, 94 ),
( 4, 79 ), (4, 87)
Теперь простой предпосылкой является лучший результат каждого участника, который представляет собой простую MAX() оценки каждого участника.
select
contestantid,
max( score ) highestScore
from
attempts
group by
contestantid
Результат приведенного выше запроса является ОСНОВОЙ окончательного рейтинга. Поэтому я поставил этот запрос в качестве источника FROM. Таким образом, вместо таблицы исходный результат является результатом вышеуказанного запроса, который я назвал «PreAgg» для предварительной агрегации для каждого участника.
select
ContestantID,
c.personName,
DENSE_RANK() OVER ( order by HighestScore DESC ) as FinalRank
from
(select
contestantid,
max( score ) highestScore
from
attempts
group by
contestantid ) preAgg
JOIN Contestants c
on preAgg.contestantid = c.id
Присоединиться к участнику достаточно просто, чтобы получить имя, но теперь взгляните на предложение DENSE_RANK(). Поскольку нет группировки по баллам, например, Олимпийских игр, где есть определенный вид спорта, и каждый вид спорта имеет самые высокие рейтинги, нам не нужен пункт «РАЗДЕЛЕНИЕ».
Предложение ORDER BY — это то, что вам нужно. В этом случае столбец HighestScore из запроса предварительного агрегирования и требуется, чтобы он был в порядке УБЫТАНИЯ, чтобы САМОЕ ВЫСОКОЕ значение было вверху и опускалось вниз. «Как» дает ему окончательное имя столбца.
DENSE_RANK() OVER ( order by HighestScore DESC ) as FinalRank
Results
ContestantID personName FinalRank
3 Jane 1
1 Bill 2
2 Mary 2
4 Mark 3
Теперь, если вам нужен только предел, такой как 3 верхних места, и у вас на самом деле было 20+ конкурентов, просто завершите это еще раз, где clase
select * from
(
select
ContestantID,
c.personName,
DENSE_RANK() OVER ( order by HighestScore DESC ) as FinalRank
from
(select
contestantid,
max( score ) highestScore
from
attempts
group by
contestantid ) preAgg
JOIN Contestants c
on preAgg.contestantid = c.id ) dr
where
dr.FinalRank < 3
Что вы пробовали? Где ты застрял? Для оказания помощи требуется немного больше деталей.