novo no mysql aqui. Estou usando o mysql versão 5.6.25-enterprise-commercial-advanced e tenho tabelas
mysql> select * from Department;
+-------+--------------+
| DepID | DepName |
+-------+--------------+
| 1 | English |
| 2 | Math |
| 3 | History |
| 4 | French |
| 5 | Geography |
| 6 | Drawing |
| 7 | Architecture |
+-------+--------------+
e
mysql> select * from Student;
+--------+----------+------------+-------+
| StudID | StudName | StudentAge | DepID |
+--------+----------+------------+-------+
| 1 | Alice | 21 | 2 |
| 2 | Alfred | 20 | 3 |
| 3 | Henry | 19 | 3 |
| 4 | Jacobs | 22 | 5 |
| 5 | Bob | 20 | 4 |
| 6 | Shane | 22 | 4 |
| 7 | Linda | 24 | 4 |
| 8 | Stacy | 20 | 1 |
| 9 | Wolfred | 21 | 2 |
| 10 | Sandy | 25 | 1 |
| 11 | Colin | 18 | 1 |
| 12 | Maria | 19 | 3 |
| 13 | Ziva | 20 | 5 |
| 14 | Mark | 23 | 5 |
| 15 | Fred | 25 | 2 |
| 16 | Vic | 25 | NULL |
| 17 | Nick | 25 | NULL |
+--------+----------+------------+-------+
Estou usando uma consulta:
SELECT Department.DepName, AVG(Student.StudentAge) AS AvgStudAge
FROM Student
RIGHT JOIN Department
ON Student.DepID = Department.DepID;
que resulta apenas em uma única linha:
+---------+------------+
| DepName | AvgStudAge |
+---------+------------+
| English | 21.2667 |
+---------+------------+
...mas acho que também deveria estar recebendo todas as outras linhas, com a coluna DepName me fornecendo algo como "inglês" ou "matemática" e a idade agregada associada sendo a idade média de todos os alunos associados a esse departamento. Por que ele retorna apenas uma linha para inglês?
Na verdade, descobri que a inserção da seguinte linha de código GROUP BY DepName;
no final da minha consulta anterior, me dá o que quero, mas não entendo por que devo ter que Agrupar por qualquer coisa.
Qualquer esclarecimento seria apreciado!
Respostas:
0 para resposta № 1Em sua consulta:
SELECT Department.DepName, AVG(Student.StudentAge) AS AvgStudAge
FROM Student
RIGHT JOIN Department
ON Student.DepID = Department.DepID;
Usando um agregado como AVG
sem usar também GROUP BY
, O SQL trata isso como uma média de todos os dados retornados, independentemente do departamento.
o DepName
que o MySql está mostrando na única linha retornadaé arbitrariamente o primeiro valor retornado. Além do MySql, um RDBMS compatível com ANSI irá gerar um erro para esta consulta, pois TODAS as colunas selecionadas devem ser apresentadas com um agregado (se não houver GROUP BY
), ou todas as colunas não agregadas devem estar no GROUP BY
cláusula (quando agrupada). O MySql é irritantemente tolerante a esse respeito e isso pode levar a bugs.
Exemplo de idade média do aluno por departamento:
SELECT Department.DepName, AVG(Student.StudentAge) AS AvgStudAge
FROM Student
RIGHT JOIN Department
ON Student.DepID = Department.DepID
GROUP BY Department.DepName;
Idade Média do Aluno de Todos os Alunos:
SELECT AVG(Student.StudentAge) AS AvgStudAge
FROM Student;
Exemplos de agregados com / sem GROUP BY
Aqui
-1 para resposta № 2
Basta adicionar Group By no último GROUP by Department.DepID
, você terá a média de todos os departamentos