2
respostas

Consulta SQLSeverII (Sub-queries)

Olá, estou cursando a parte de sub-queries do SQL Server II e gostaria de saber qual seria a melhor forma de consultar a média de cada aluno por curso, a média do curso e a diferença entre as médias. Meu código ficou assim:

USE SQL_AVANCADO;

SELECT A1.NOME, C1.NOME,

(SELECT AVG(NC.NOTA) AS MEDIA_CURSO FROM NOTA NC INNER JOIN RESPOSTA R ON R.ID = NC.RESPOSTA_ID INNER JOIN EXERCICIO E ON E.ID = R.EXERCICIO_ID INNER JOIN SECAO S ON S.ID = E.SECAO_ID INNER JOIN CURSO C ON C.ID = S.CURSO_ID WHERE C.ID = C1.ID) MEDIA_CURSO,

(SELECT AVG(NA.NOTA) AS MEDIA_ALUNO FROM NOTA NA INNER JOIN RESPOSTA R ON R.ID = NA.RESPOSTA_ID INNER JOIN EXERCICIO E ON E.ID = R.EXERCICIO_ID INNER JOIN SECAO S ON S.ID = E.SECAO_ID INNER JOIN CURSO C ON C.ID = S.CURSO_ID INNER JOIN ALUNO A ON A.ID = R.ALUNO_ID WHERE C.ID = C1.ID AND A.ID = A1.ID) MEDIA_ALUNO,

((SELECT AVG(NC.NOTA) AS MEDIA_CURSO FROM NOTA NC INNER JOIN RESPOSTA R ON R.ID = NC.RESPOSTA_ID INNER JOIN EXERCICIO E ON E.ID = R.EXERCICIO_ID INNER JOIN SECAO S ON S.ID = E.SECAO_ID INNER JOIN CURSO C ON C.ID = S.CURSO_ID WHERE C.ID = C1.ID) -

(SELECT AVG(NA.NOTA) AS MEDIA_ALUNO FROM NOTA NA INNER JOIN RESPOSTA R ON R.ID = NA.RESPOSTA_ID INNER JOIN EXERCICIO E ON E.ID = R.EXERCICIO_ID INNER JOIN SECAO S ON S.ID = E.SECAO_ID INNER JOIN CURSO C ON C.ID = S.CURSO_ID INNER JOIN ALUNO A ON A.ID = R.ALUNO_ID WHERE A.ID = A1.ID AND C.ID = C1.ID)) AS DIFERENCA

FROM NOTA N INNER JOIN RESPOSTA R ON R.ID = N.RESPOSTA_ID INNER JOIN EXERCICIO E ON E.ID = R.EXERCICIO_ID INNER JOIN SECAO S ON S.ID = E.SECAO_ID INNER JOIN CURSO C1 ON C1.ID = S.CURSO_ID INNER JOIN ALUNO A1 ON A1.ID = R.ALUNO_ID GROUP BY A1.NOME, C1.NOME, A1.ID, C1.ID ORDER BY A1.NOME, C1.NOME

--================================================--

Seria essa uma boa forma de consultar? Existe alguma forma mais adequada?

Desde já agradeço!

2 respostas

Boa tarde, Depende muito, servidor, maquina, e banco de dados

se voce tiver tabela com muito GB de dados esses scritp seu ja ficaria lento muito subselect e faz calculo ainda. o correto e trabalhar com maior numero de join amarrando o maior numero de tabela e colocando filtros.

Sempre trabalhar os seus script priorizando a rapidez do relatorio . e analisando a quantidade de usuarios vao usar esse relatorio para nao sobrecarregar o banco.

espero ter ajudado sucesso.

Olá Rubens,

Estava com a mesma dúvida que vc e montei a seguinte query:

Select a.nome ,c.nome ,avg(n.nota) media_aluno ,avg(n.nota) - (select avg(n1.nota) from nota n1) diferença

,media_curso = ( Select avg(n.nota) media_curso

From nota n Join resposta r On n.resposta_id = r.id Join exercicio e On r.exercicio_id = e.id Join secao s On e.secao_id = s.id Join curso c1 On s.curso_id = c1.id Group By c1.nome Having c1.nome = c.nome )

From nota n Join resposta r On n.resposta_id = r.id Join exercicio e On r.exercicio_id = e.id Join secao s On e.secao_id = s.id Join curso c On s.curso_id = c.id Join aluno a On r.aluno_id = a.id Group By c.nome, a.nome

Apesar de não ter ficado muito "elegante", trouxe os mesmos resultados que a sua query, só que um pouco mais performática analisando o plano de execução (Ctrl + L).

Acredito que a diferença esteja no fato dos dados serem agrupados e filtrados pelo having, sendo processado um menor número de dados.