Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

Dúvida no Ex. 3 da Aula 1 - Alunos sem matrícula e o EXISTS

Essa condição do gabarito me parece errada para apresentar as informações pedidas no exercício:

...Ou mesmo exists, invertendo a condição:

select a.nome from aluno a where exists ( select m.id from matricula m where m.aluno_id = a.id and m.data );

pois se eu quero, segundo o enunciado, todos aqueles que não foram matriculados no intervalo de 45 dias atrás, essa condição simplesmente vai me apresentar 4 alunos, que são justamente aqueles que não foram matriculados no período de 45 dias atrás.

Porém existe um quinto aluno, o Paulo da Silva, que não está matriculado em nenhum curso, logo ao rodar a condição exists, ele não me apresenta esse aluno pois a m.id nunca terá um valor pra ele já que ele não tem numero de matricula válido. Entretanto, ele também é um aluno da tabela alunos e ele também não foi matriculado em nenhum curso nos últimos 45 dias.

Justamente quando você roda o código do gabarito usando o NOT exists, ele retorna os 5 alunos, incluindo o Paulo da Silva, e quando você roda a inversão, ele retorna os 4. Isso acontece justamente porquê o quinto aluno não está matriculado e não aparece com o exists usando a condição de comparação de matricula com a id de aluno.

faça o teste (código do gabarito utilizando o not exists):

select a.nome from aluno a where not exists(select m.id from matricula m where m.aluno_id = a.id and m.data > now() - interval 45 day);

A condição que funcionou pra mim e que pode ser invertida com o exists, tira do código a parte da comparação entre m.aluno_id com a a.id, dessa forma, ele me mostrará todos os alunos que não foram matriculados no período de 45 dias apenas pela condição da DATA na tabela de matrícula.. que no caso do Paulo da Silva é de qualquer forma menor que 45 dias atrás, já que ele não está matriculado.

assim, usando o exists:

select a.nome from aluno a where exists ( select m.id from matricula m where data < now() - interval 45 day);

ou seja, me mostre o nome dos alunos quando esta condição me retornar valor: me mostre o id da tabela de matricula em que as datas sejam ANTERIORES a 45 dias atrás.

e assim invertendo com o not exists:

select a.nome from aluno a where NOT exists ( select m.id from matricula m where data > now() - interval 45 day);

me mostre o nome dos alunos em que a data de matrícula não seja POSTERIOR a data de hoje menos 45 dias atrás.

Ambas deram certo e retornaram os nomes dos mesmos alunos.

Me ajudem companheiros, estou viajando? Rodem as buscas ai e vejam se quando vcs utilizam o código do gabarito não fica faltando justamente um aluno que também não foi matriculado posteriormente a data de 45 dias atrás.

8 respostas

Esse código que você colocou primeiro não especifica a data que você requer que tenham se matriculado...

select a.nome from aluno a where exists ( select m.id from matricula m where m.aluno_id = a.id and m.data );

Este seria o código corrigido:

select a.nome from aluno a where exists ( select m.id from matricula m where m.aluno_id = a.id and m.data > now() - interval 45 day);

Esse código acima diz: "Selecione um aluno que tenha se matriculado em algum curso nos últimos 45 dias..."

E o retorno "Empty set" é válido já que ninguém se matriculou nos últimos 45 dias.

Agora este código abaixo diz: "Selecione os alunos que não se matricularam nos últimos 45 dias"

select a.nome from aluno a where not exists ( select m.id from matricula m where m.aluno_id = a.id and m.data > now() - interval 45 day);

Estes dois últimos códigos estão corretos, só não lembro se eles são o gabarito do problema. Se forem, tudo bem. Se não o gabarito está incompleto como você alertou...

Exatamente Otávio, esse primeiro código que você diz é o código que está no gabarito, ele está incompleto, como você disse.

Seguindo o seu raciocínio, o exercício pede que selecionamos os alunos que não se matricularam nos últimos 45 dias, como vc descreveu no último código com o NOT exists...

Depois ele diz que quer a inversão, ou seja, usando o exists, ainda para descrever os alunos que não se matricularam no últimos 45 dias, e da aquele código incompleto como a solução.. aquele código apenas mostrará os alunos que estão matriculados...

enfim, acho que tá errado mesmo.

solução

Verdade. Gabarito realmente está errado...

O exercicio é : Busque todos os alunos que não tiveram nenhuma matrícula nos últimos 45 dias, usando a instrução EXISTS. A resposta que eu fiz foi : select a.nome from aluno a where exists ( select m.id from matricula m where m.aluno_id=a.id and m.data < now() - interval 45 day); A resposta que o instrutor usou colocando o exists foi : select a.nome from aluno a where exists ( select m.id from matricula m where m.aluno_id = a.id and m.data ); Acho que ele errou nessa ai.

Pelo visto, o erro ainda persiste.

Pessoal do Alura, poderiam verificar?

Acredito a resolução do exercício fica um pouco complicada com a utilização do exists, principalmente pela possibilidade de alguns alunos não possuirem matriculas e não consigo visualizar uma forma de garantir a afirmação do exists e ao mesmo tempo a negação dos 45 dias de matricula.

A forma mais simples de resolver o exercício e com o not exists ou até mesmo o not in utilizando uma subquery.

Esses dois Sql abaixo são equivalentes

select a.nome from aluno a where not exists (select m.id from matricula m where m.aluno_id = a.id and m.data > now() - interval 45 day);
select a.nome from aluno a where exists (select m.id from matricula m where m.aluno_id = a.id or m.data < now() - interval 45 day);

Felipe Gonzaga, as duas consultas que você apresentou não são equivalentes. A segunda consulta tem o mesmo retorno da primeira, apenas por coincidência, porque na base de testes não existe nenhuma matrícula que tenha sido realizada nos últimos 45 dias. Como foi utilizado o comando OR basta um aluno estar matriculado (m.aluno_id = a.id) para que ele seja retornado, ou seja não está sendo levado em consideração a data de matrícula como requisitado no exercício.

Vinicius Torrubia, concordo plenamente, a inversão do comando apresentada na explicação não resolve o problema , visto que não seleciona os alunos não matriculados e estes também não se matricularam nos ultimos 45 dias como no enunciado:

"Busque todos os alunos que não tiveram nenhuma matrícula nos últimos 45 dias, usando a instrução EXISTS."