Reputation: 1450
I have a small system that accepts votes, on my query I'm selecting the vote(name of user) and the total of votes for this user. My Idea is to only display the user with more votes, with the query that i have I know that i can add ORDER BY and get the first value which will be the one with the highest umber of votes. But i'm trying to identifie if two persons have the number of votes. any ideas how can i do that?
I'm using cgi.
my $connection = $MY_CONNECTION->prepare("SELECT voto, COUNT(*) total FROM votos WHERE mes = 12 GROUP BY vote HAVING COUNT(*) > 0 ORDER BY COUNT(*)");
$connection->execute || print "ERROR 1";
my @resultados;
my $info = '';
while ($info = $connection->fetchrow_hashref()) {
my $nombre = $info->{voto};
my $totalVotos = $info->{total};
my $winner = "";
my $temp2 = "";
my $temp = $totalVotos ;
if ($temp2 => $temp) {
$temp2 = $totalVotos ;
$winner = $nombre ;
}
print "<p><strong>Winner: </strong> $winner </p> ";
print "<hr>";
}
Upvotes: 1
Views: 184
Reputation: 16662
You can return everyone who has the highest number of votes (and how many votes) with:
select voto, count(*) as total from votos
where mes = 12
group by voto -- I assume "vote" in your question was typo
having total = (
select max(ct) from (
select voto,count(*) as ct from votos group by voto
)
)
and total > 0 -- from your original but not sure it can fail
;
You may also be able to use a rank()
function.
Without modifying your SQL, you could change the perl to something like:
# ...
# initialisation shouldn't be inside while loop
my $winner = "";
my $temp2 = "";
while ($info = $connection->fetchrow_hashref()) {
my $nombre = $info->{voto};
my $totalVotos = $info->{total};
if ($temp2 < $totalVotos) { # your original "=>" seems wrong
$temp2 = $totalVotos;
@winner = $nombre;
elsif ($temp2 == $totalVotos) {
push @winner, $nombre;
}
}
# postprocessing shouldn't be inside while loop
$winner = join(", ", @winner); # or whatever
print "<p><strong>Winner: </strong> $winner </p> ";
print "<hr>";
Upvotes: 2
Reputation: 1269563
I would recommend rank()
:
SELECT voto, total
FROM (SELECT voto, COUNT(*) as total,
RANK() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM votos v
WHERE mes = 12
GROUP BY voto
) v
WHERE seqnum = 1;
Note that HAVING COUNT(*) > 0
does nothing. In your query, it is not possible for COUNT(*)
to be equal to or less than 0
.
Upvotes: 1
Reputation: 13006
use subquery
then apply order by
, to limit the result by 2 add limit 2
.
select t1.voto, t1.ct as total from (
SELECT voto, count(1) ct FROM votos
WHERE mes = 12
GROUP BY voto
HAVING COUNT(1) > 1) t1
order by t1.total desc limit 2
Upvotes: 1