Não consegui resolver esse problema no hackerrank e tive que procurar a solução. Eu estava entrando nas mesas erradas.
São 4 tabelas:
- hackers
- desafios
- envios feitos por hackers e suas pontuações
- tabela de dificuldade com níveis.
a descrição da tarefa:
Escreva uma consulta para imprimir o respectivo hacker_id e o nome dos hackers que alcançaram a pontuação máxima em mais de um desafio.
Campos da tabela de envios: submit_id, hacker_id, challenge_id, score
campos da tabela de desafios: challenge_id, hacker_id, dificuldade_level
A forma como entrei: hackers + desafios, desafios + dificuldade, desafios + envios.
select
hackers.hacker_id, name
from submissions inner join challenges on submissions.challenge_id = challenges.challenge_id
inner join difficulty on difficulty.difficulty_level = challenges.difficulty_level
inner join hackers on
challenges.hacker_id = hackers.hacker_id -- here is wrong part!
where difficulty.score = submissions.score and difficulty.difficulty_level = challenges.difficulty_level
group by hackers.hacker_id, name
having count( challenges.challenge_id)> 1
order by count( challenges.challenge_id) desc, hackers.hacker_id
No entanto, o caminho certo era quase o mesmo - exceto que eu deveria ter participado de envios + hackers por hacker_id vs não envios + desafios por challenge_id.
A forma correta:
select
hackers.hacker_id,name
from submissions inner join challenges on submissions.challenge_id = challenges.challenge_id
inner join difficulty on difficulty.difficulty_level = challenges.difficulty_level
inner join hackers on submissions.hacker_id = hackers.hacker_id
where difficulty.score = submissions.score and difficulty.difficulty_level = challenges.difficulty_level
group by hackers.hacker_id, name
having count( challenges.challenge_id)> 1
order by count( challenges.challenge_id) desc, hackers.hacker_id
Qual é a lógica por trás da junção de envios + desafios por challenge_id vs envios + hackers por hacker_id?
por que produz resultado diferente? Um hacker faz envios, então não importa se eu entro no desafio+submissão+hackers ou submissão+hacker+desafio...
É um palpite porque você não forneceu o link para o desafio (no markdown você tem que fazer links como,[this problem](http://whatever.com)
mas clicar no link leva para http://this%20problem, então acho que o markdown está quebradoVocê disse que tem tabelas:
Assim, podemos claramente ter "um hacker pode responder a muitos desafios" e "um desafio tem muitos hackers respondendo", ou seja, muitos relacionamentos, então precisamos de uma tabela no meio para dividi-lo e rastrear qual hacker respondeu a qual desafio, e isso é a tabela de Envios fazendo essa divisão
Esta parte interessante aqui, e possivelmente colocada deliberadamente para enganar as pessoas, é que o Challenge também tem uma coluna de ID de hacker. Por alguma razão, as tabelas de classificação de hackers rastreiam um relacionamento hacker-challenge que não tem nada a ver com um envio, ou seja, o ID do hacker na tabela de desafios é algo em que pode haver apenas um hacker para esse desafio, como o hacker que o criou ou o hacker que primeiro obteve a pontuação perfeita, ou o hacker que é responsável por marcar as respostas nele, ou o hacker que o pegou mais recentemente.
Seja qual for o motivo, você disse que se juntou a esse ID de hacker, o que , na minha opinião, é a coisa errada a fazer , porque não tem relação com a questão de vários hackers que enviaram: pode ser que o hacker
challenge.hacker_id
no submissão ao desafio, eles simplesmente o escreveram e nunca o responderam. Portanto, não pode lhe dar as respostas que o desafio busca. Provavelmente é para pegar você e é uma das razões pelas quais, quando estou projetando um esquema de banco de dados, pretendo colocar o motivo de uma coluna em seu nome em casos como este; ou seja, na mesa do Desafio eu poderia ter chamadoauthor_hackerid
oumoderator_hackerid
para descrever não apenas para onde ele se vincula (tabela de hacker no ID do hacker), mas por que ele se vincula lá (autor, moderador, primeiro vencedor, tomador recente), especialmente se houver várias pessoas .. (embora nesse caso possa fazer mais sentido ter outra tabela, como submissão) que divide hacker e desafio e fornece uma razão pela qual esse hacker está relacionado a esse desafio)Lembre-se de que só porque duas colunas têm o mesmo nome, isso não significa que sejam opções alternativas de junção. Mesmo as colunas que participaram de uma junção antes não são alternativas, se for uma junção esquerda. Se for uma junção interna, jogo justo:
mas estes podem dar resultados diferentes:
Essa pequena, mas crítica diferença na segunda consulta de ambas as tabelas deixadas para unir a pode ser enorme