First of all, let's generate test records:
INSERT INTO 'votos' ('Id','Candidato','Genero','Edad') VALUES (1,"josé","masculino",42),(2,"josé","masculino",42),(3,"neder","masculino",28),(4,"josé","masculino",42),(5,"neder","masculino",28),(6,"josé","masculino",42),(7,"josé","masculino",42),(8,"josé","masculino",42),(9,"josé","masculino",42),(10,"neder","masculino",28);
INSERT INTO 'votos' ('Id','Candidato','Genero','Edad') VALUES (11,"neder","masculino",28),(12,"neder","masculino",28),(13,"josé","masculino",42),(14,"hector","masculino",37),(15,"josé","masculino",42),(16,"hector","masculino",37),(17,"hector","masculino",37),(18,"josé","masculino",42),(19,"neder","masculino",28),(20,"hector","masculino",37);
+----+-----------+-----------+------+
| Id | Candidato | Genero | Edad |
+----+-----------+-----------+------+
| 1 | josé | masculino | 42 |
| 2 | josé | masculino | 42 |
| 3 | neder | masculino | 28 |
| 4 | josé | masculino | 42 |
| 5 | neder | masculino | 28 |
| 6 | josé | masculino | 42 |
| 7 | josé | masculino | 42 |
| 8 | josé | masculino | 42 |
| 9 | josé | masculino | 42 |
| 10 | neder | masculino | 28 |
| 11 | neder | masculino | 28 |
| 12 | neder | masculino | 28 |
| 13 | josé | masculino | 42 |
| 14 | hector | masculino | 37 |
| 15 | josé | masculino | 42 |
| 16 | hector | masculino | 37 |
| 17 | hector | masculino | 37 |
| 18 | josé | masculino | 42 |
| 19 | neder | masculino | 28 |
| 20 | hector | masculino | 37 |
+----+-----------+-----------+------+
Generator used link
MySQL online terminal: link
Now based on the previous records, you are supposed to get from among (josé, neder and hector) only those that do not exceed the average of the total votes for each candidate, something you can do is store first in a variable of session this average, like this:
SELECT @promedio:=AVG(num_votos)
FROM (
SELECT Candidato, COUNT(Candidato) AS num_votos
FROM votos
GROUP BY Candidato
) AS tabla_promedio;
+---------------------------+
| @promedio:=AVG(num_votos) |
+---------------------------+
| 6.666666666 |
+---------------------------+
Then you simply make a query where you use that session variable as a filter;
SELECT Candidato, COUNT(Candidato) AS num_votos
FROM votos
GROUP BY Candidato
HAVING num_votos < @promedio;
+--------------+-----------+
| Candidato | num_votos |
+--------------+-----------+
| hector | 4 |
| neder | 6 |
+--------------+-----------+
PD: Recommendation
You must bear in mind that the design you implement is not optimal, since it is not normalized in the least and therefore does not take advantage of the teachings that promote relational databases. To be more clear I will show you the following example:
+----+-----------+-----------+------+
| Id | Candidato | Genero | Edad |
+----+-----------+-----------+------+
| 1 | josé | masculino | 42 |
| 2 | josé | masculino | 78 |
| 3 | neder | masculino | 53 |
| 4 | josé | masculino | 27 |
| 5 | neder | masculino | 63 |
| 6 | josé | femenino | 28 |
| 7 | josé | masculino | 66 |
| 8 | josé | masculino | 28 |
| 9 | josé | masculino | 59 |
| 10 | neder | masculino | 54 |
| 11 | neder | masculino | 26 |
| 12 | neder | masculino | 71 |
| 13 | josé | masculino | 80 |
| 14 | hector | masculino | 25 |
| 15 | josé | masculino | 71 |
| 16 | hector | masculino | 37 |
| 17 | hector | masculino | 72 |
| 18 | josé | femenino | 66 |
| 19 | neder | masculino | 49 |
| 20 | hector | masculino | 74 |
+----+-----------+-----------+------+
Realize that there are different ages for the same person, even José gets to change sexuality in some occasions, this is called data redundancy, but it is something that I will not go into great detail, however I will sketch you A guide:
Table of candidates
+----+-----------+-----------+------+
| Id | Candidato | Genero | Edad |
+----+-----------+-----------+------+
| 1 | josé | masculino | 42 |
| 3 | neder | masculino | 53 |
| 14 | hector | masculino | 74 |
+----+-----------+-----------+------+
Table of votes
+----+-------------+
| Id | IdCandidato |
+----+-------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
| 4 | 1 |
| 5 | 3 |
| 6 | 1 |
| 7 | 1 |
| 8 | 1 |
| 9 | 1 |
| 10 | 3 |
| 11 | 3 |
| 12 | 3 |
| 13 | 1 |
| 14 | 14 |
| 15 | 1 |
| 16 | 14 |
| 17 | 14 |
| 18 | 1 |
| 19 | 3 |
| 20 | 14 |
+----+-------------+
In this case in the candidates table you only have competent information to these and there are no duplicate records, jose can now enjoy defined sexuality and each member of the electoral group has a unique age.
Notice then that in the votes table, you relate each record to a candidate through its Id
, now you can keep a count of the votes in a better way and it will be this one that you use as a grouper.
SELECT @promedio:=AVG(num_votos)
FROM (
SELECT Candidato, COUNT(Candidato) AS num_votos
FROM candidatos
GROUP BY Candidato
) AS tabla_promedio;
SELECT Candidato, COUNT(Candidato) AS num_votos
FROM votos
INNER JOIN candidatos ON voto.IdCandidato = candidato.Id
GROUP BY Candidato
HAVING num_votos < @promedio;
You will see that now the only difference is the line INNER JOIN candidatos ON voto.IdCandidato = candidato.Id
this only thing that defines is that now to obtain the names of the candidates you must gather the corresponding records of the table votos
and the table candidatos
since as it is evident the field candidatos
does not exist in the first one.
I hope I have not ended up confusing them and that it will be useful for them.