Candidates whose average is below the general average

2

I want to complete this SQL statement, so that I only return the candidates whose average is lower than the general average:

SELECT Candidato, COUNT(Candidato) AS num_votos
FROM votos
GROUP BY Candidato

The structure of the table is:

CREATE TABLE votos ( 
    Id int(11) NOT NULL, 
    Candidato varchar(20) NOT NULL, 
    Genero varchar(10) NOT NULL, 
    Edad tinyint(4) NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

The vote count is doing it according to the number of times the name of the candidate is repeated in the candidate column.

    
asked by Fred Albert Morales 03.07.2017 в 07:53
source

2 answers

3

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.

    
answered by 03.07.2017 в 10:37
0

Good, you should show your complete table, even so I'm going to assume that your table has the Candidate column and the Votes column and that your table is called TableVideos :

select Candidato, Votos
    from   tablaVotos
    where  Votos < (select avg(Votos)
                     from   tablaVotos);

This query returns the values that are less than average, if you have any questions about this, do not hesitate to tell me.

I hope it helps, greetings!

    
answered by 03.07.2017 в 08:36