My table is:
id code batch price qty
---|----- |----- |-----|---------
1 | 107 | 1 | 39 | 399
2 | 107 | 1 | 39 | 244
3 | 107 | 2 | 40 | 555
4 | 108 | 1 | 70 | 300
5 | 108 | 2 | 60 | 200
6 | 109 | 2 | 50 | 500
7 | 109 | 2 | 50 | 600
8 | 110 | 2 | 75 | 700
My desired result is (i want this result as output)
id code batch price
---|----- |----- |-----|
3 | 107 | 2 | 40 |
4 | 108 | 1 | 70 |
3 | 109 | 2 | 50 |
8 | 110 | 2 | 75 |
i write this query
SELECT `id`,`code`,`batch` max(`price`) FROM `table_name` where `qty` > 0 group by `code`
my output is
id code batch price
---|----- |----- |-----|
1 | 107 | 1 | 40 |
4 | 108 | 1 | 70 |
6 | 109 | 2 | 50 |
8 | 110 | 2 | 75 |
i need id and batch where the price is max
Another way to get highest record per group
select *
from demo a
where (
select count(*)
from demo b
where a.code = b.code
and case when a.price = b.price then a.id < b.id else a.price < b.price end
) = 0
I assume id is auto increment so in case there is a tie in max price from groups you can use a CASE to pick the latest id
Demo
You could use join on the max value grouped by code
select a.id, a.code, a.batch, b.max_price
from table_name a
inner join (
select code, max(price) as max_price
from table_name
group by code
) b on a.code = b.code and a.price = b.max_price
and if you have more that a row with same code, price you could use
select max(a.id), a.code, a.batch, b.max_price
from table_name a
inner join (
select code, max(price) as max_price
from table_name
group by code
) b on a.code = b.code and a.price = b.max_price
group by a.code, a.batch, b.max_price
select id,batch from table_name order by price desc limit 0,1
Sort by desc with price
Select the top row using limit
Order by the price and then limit the result to 1 :)
SELECT id, batch
FROM table_name
ORDER BY price DESC
LIMIT 1
Give a row number group by code and in the descending order of price columns. Then select the rows having row number 1.
Query
select t1.`id`, t1.`code`, t1.`batch`, t1.`price` from (
select `id`, `code`, `batch`, `price`, (
case `code` when #curA
then #curRow := #curRow + 1
else #curRow := 1 and #curA := `code` end
) as `rn`
from `MyTable` t,
(select #curRow := 0, #curA := '') r
order by `code`, `price` desc
)t1
where t1.`rn` = 1
order by `code`;
Find a demo here
Try this:
SELECT `id`,`code`,`batch`, `price`
FROM `table_name`
WHERE `qty` > 0
GROUP BY `code` HAVING `price` = max(`price`)
I didn't understand you need single result or multiple. but this works fine if you need only max id.
SELECT id
FROM table
WHERE id=(
SELECT max(price) FROM table
)
Note : if the value of max(id) is not unique, multiple rows are returned.
try this
SELECT MAX(price) AS price, id, batch
FROM table_name
Related
i am trying to get rank and number of same rank by votes but unfortunately no success.
Here my table structure:
| ID| user_id | votes |
| --| ------- | ----- |
| 1 | D10 | 15 |
| 2 | D5 | 9 |
| 3 | D20 | 9 |
| 4 | D23 | 7 |
| 5 | D35 | 3 |
| 6 | D65 | 2 |
I need the rank of user according to votes, referring to above table i need the rank as:
| user_id | Rank|
| ------- | ----|
| D10 | 1 |
| D5 | 2 |
| D20 | 2 |
| D23 | 3 |
| D35 | 4 |
| D65 | 5 |
and also i need the number of rank, referring to above ranks i need:
Rank 1 = 1
Rank 2 = 2
Rank 3 = 1
Rank 4 = 1
rank 5 = 1
i tried to get rank :
SELECT user_id, votes, FIND_IN_SET( votes, (
SELECT GROUP_CONCAT( DISTINCT votes
ORDER BY votes DESC ) FROM table)
) AS rank
FROM votes
the above query i tried referring to this answer to get the ranks but i am getting error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
near '( votes , (SELECT GROUP_CONCAT( DISTINCT votes ORDER BY votes DESC
)
i need the desired result using PHP and MySQL.
On MySQL 8+ you could use windows function dense_rank and count over
with votes_rank as (
select *,
dense_rank() over (order by votes desc) as rnk
from votes
) , count_rank as
( select votes_rank.*,
count(*)over (partition by rnk) as cnt
from votes_rank
) select id,
user_id,
votes,
rnk as votes_rank,
cnt as count_rank
from count_rank;
https://dbfiddle.uk/o1DiPyDz
Consider the following data,
CREATE TABLE votes (
id int,
user_id varchar(10),
votes int );
insert into votes values (1,'D10',15), (2,'D5 ',9), (3,'D20',9), (4,'D23',7), (7,'D50',7), (5,'D35',3), (6,'D65',2);
Result:
id user_id votes votes_rank count_rank
1 D10 15 1 1
2 D5 9 2 2
3 D20 9 2 2
4 D23 7 3 2
7 D50 7 3 2
5 D35 3 4 1
6 D65 2 5 1
Edit,
On MySQL version <8
select tbl.id,tbl.user_id,tbl.votes,tbl.rnk,votes_count
from (SELECT a.id,
a.user_id,
a.votes,
count(b.votes)+1 as rnk
FROM votes a
left join votes b on a.votes<b.votes
group by a.id,a.user_id,a.votes
order by a.votes desc
) as tbl
inner join (select rnk,count(rnk) as votes_count
from ( SELECT a.id,
a.user_id,
a.votes,
count(b.votes)+1 as rnk
FROM votes a
left join votes b on a.votes<b.votes
group by a.id,a.user_id,a.votes
order by a.votes desc
) a2
group by rnk
) as tbl1 on tbl1.rnk = tbl.rnk;
https://dbfiddle.uk/XlsBjrZO
it will be very difficult to explain this in words so I will attempt small example to explain you what i want:
for example i have this SQL-Server table
+-------+-------+------+
| TestID| Start | End |
+-------+-------+------+
| 1 | DateA | DateB|
| 2 | DateA | DateB|
| 3 | DateA | DateB|
| 4 | DateA | |
+-------+-------+------+
What i want is this table:
$Rest = 1000
+-------+-------+------+----------+-----------+----------+
| TestID| Start | End | Testtime | Totaltime | Resttime |
+-------+-------+------+----------+-----------|----------|
| 1 | DateA | DateB| 214 | 214 | 786 |
| 2 | DateA | DateB| 100 | 314 | 686 |
| 3 | DateA | DateB| 200 | 514 | 486 |
| 4 | DateA | | | | |
+-------+-------+------+----------+-----------+----------+
i have the problem to understand what i have to combine
here is the code to get the first SQL-Server table
SELECT TestID, Start, End, DATEDIFF(hour, Start, End) AS Testtime
FROM Testresults
WHERE TesttableID = 1
Each Row has the TesttableID = 1 thx for help.
Edit : SQL Server Version: 9.0.5057
Edit : I get results but not the right one, they are switched in Totaltime and Resttime
SELECT t1.TestID,
t1.start,
t1.end,
t1.TesttableID,
DATEDIFF(hour,t1.start,t1.end) as Testtime,
(SELECT SUM(DATEDIFF(hour,t2.start,t2.end))
FROM Testresults t2
WHERE t2.TestID <= t1.TestsID AND t2.TesttableID = 1 ) AS Totaltime,
(SELECT 1000-SUM(DATEDIFF(hour,t2.start,t2.end))
FROM Testresults t2
WHERE t2.TestID <= t1.TestIDAND t2.TesttableID = 1 ) AS Resttime FROM Testresults t1 WHERE t1.TesttableID = 1
What i get is These Results, they switched..:
+-------+-------+------+----------+-----------+----------+
| TestID| Start | End | Testtime | Totaltime | Resttime |
+-------+-------+------+----------+-----------|----------|
| 1 | DateA | DateB| 214 | 514 | 486 |
| 2 | DateA | DateB| 100 | 300 | 700 |
| 3 | DateA | DateB| 200 | 200 | 800 |
| 4 | DateA | | | | |
+-------+-------+------+----------+-----------+----------+
You could try this:
SELECT TestId,
Start,
End,
Testtime,
SUM(Testtime) OVER (ORDER BY TestId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
1000 - SUM(Testtime) OVER (ORDER BY TestId ROWS BETWEEN AND UNBOUNDED PRECEDING AND CURRENT ROW)
FROM MyTable
For SQL Server 2005 you could use JOIN to accomplish this:
select t1.testid,
t1.start,
t1.end,
DATEDIFF(hour, t1.Start, t1.End),
sum(DATEDIFF(hour, t2.Start, t2.End)),
1000 - sum(DATEDIFF(hour, t2.Start, t2.End))
from MyTable t1
join MyTable t2 on t1.testid >= t2.testid
group by t1.testid, t1.start, t1.end, t1.Start, t1.End
Based on the sample data we have this gets you the result:
DECLARE #Rest int = 1000;
WITH VTE AS (
SELECT *
FROM (VALUES(1,'DateA','DateB',214),
(2,'DateA','DateB',100),
(3,'DateA','DateB',200),
(4,'DateA',NULL,NULL)) V(TestID,[Start],[End],Testtime))
SELECT VTE.TestID,
VTE.Start,
VTE.[End],
VTE.Testtime,
CASE WHEN [End] IS NOT NULL THEN SUM(VTE.Testtime) OVER (ORDER BY VTE.TestID ASC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) END AS TotalTime,
CASE WHEN [End] IS NOT NULL THEN #Rest - SUM(VTE.Testtime) OVER (ORDER BY VTE.TestID ASC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) END AS RestTime
FROM VTE;
Note that you likely need to implement some kind of PARTITION BY in the OVER clause, but I have no idea what that would need to be based on the limtied data we have.
You Can try this :
CREATE TABLE #MyTable
(PrimaryKey int PRIMARY KEY,
DateValueBegin DATETIME,
DateValueEnd DATETIME,
NbValue int
);
GO
INSERT INTO #MyTable
SELECT 1, DATEADD(HOUR,-2,GETDATE()), GETDATE(), 214
UNION
SELECT 2, DATEADD(HOUR,-2,GETDATE()), DATEADD(HOUR,-1,GETDATE()), 100
UNION
SELECT 3, DATEADD(HOUR,-2,GETDATE()), GETDATE(), 200
UNION
SELECT 4, DATEADD(HOUR,-1,GETDATE()), NULL, 210
UNION
SELECT 5, DATEADD(HOUR,-1,GETDATE()), NULL, 0;
SELECT *, SUM(NbValue) OVER(ORDER BY PrimaryKey
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as 'Totaltime',
1000 - SUM(NbValue) OVER(ORDER BY PrimaryKey
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) As 'RestTime' FROM #MyTable
DROP TABLE #MyTable
Explain at this post : Calculate a Running Total in SQL Server
RESULT :
PrimaryKey DateValueBegin DateValueEnd NbValue Totaltime RestTime
1 2019-01-17 09:48:05.123 2019-01-17 11:48:05.123 214 214 786
2 2019-01-17 09:48:05.123 2019-01-17 10:48:05.123 100 314 686
3 2019-01-17 09:48:05.123 2019-01-17 11:48:05.123 200 514 486
4 2019-01-17 10:48:05.123 NULL 210 724 276
5 2019-01-17 10:48:05.123 NULL 0 724 276
To user on previous SQL Server Version you can check at this post: http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal.aspx
REVISION For previous SQL version :
CREATE TABLE #MyTable
(PrimaryKey int PRIMARY KEY,
DateValueBegin DATETIME,
DateValueEnd DATETIME
);
GO
INSERT INTO #MyTable
SELECT 1, DATEADD(HOUR,-214,GETDATE()), GETDATE()
UNION
SELECT 2, DATEADD(HOUR,-100,GETDATE()), DATEADD(HOUR,-1,GETDATE())
UNION
SELECT 3, DATEADD(HOUR,-200,GETDATE()), GETDATE()
UNION
SELECT 4, DATEADD(HOUR,-1,GETDATE()), NULL
UNION
SELECT 5, DATEADD(HOUR,-1,GETDATE()), NULL;
SELECT * FROM #MyTable
SELECT PrimaryKey,
DateValueBegin,
DateValueEnd,
DATEDIFF(hour,DateValueBegin,IIF(DateValueEnd IS NOT NULL ,DateValueEnd, DateValueBegin)) as Testtime,
(SELECT SUM(DATEDIFF(hour,DateValueBegin,IIF(DateValueEnd IS NOT NULL ,DateValueEnd, DateValueBegin)))
FROM #MyTable t2
WHERE t2.PrimaryKey <= t1.PrimaryKey ) AS Totaltime,
DATEDIFF(hour,DateValueBegin,IIF(DateValueEnd IS NOT NULL ,DateValueEnd, DateValueBegin)) as Testtime,
(SELECT 1000-SUM(DATEDIFF(hour,DateValueBegin,IIF(DateValueEnd IS NOT NULL ,DateValueEnd, DateValueBegin)))
FROM #MyTable t3
WHERE t3.PrimaryKey <= t1.PrimaryKey ) AS Resttime
FROM #MyTable t1
DROP TABLE #MyTable
RESULT :
PrimaryKey DateValueBegin DateValueEnd Testtime Totaltime Testtime Resttime
1 2019-01-08 18:17:35.430 2019-01-17 16:17:35.430 214 214 214 786
2 2019-01-13 12:17:35.430 2019-01-17 15:17:35.430 99 313 99 687
3 2019-01-09 08:17:35.430 2019-01-17 16:17:35.430 200 513 200 487
4 2019-01-17 15:17:35.430 NULL 0 513 0 487
5 2019-01-17 15:17:35.430 NULL 0 513 0 487
Sorry but i didn't know your all configuration
Can you try this :
SELECT t1.TestID,
t1.start,
t1.end,
t1.TesttableID,
DATEDIFF(hour,t1.start,t1.end) as Testtime,
(SELECT SUM(DATEDIFF(hour,t2.start,t2.end))
FROM Testresults t2
WHERE t2.TestID <= t1.TestsID AND t2.TesttableID = 1 ) AS Totaltime,
(SELECT 1000-SUM(DATEDIFF(hour,t2.start,t2.end))
FROM Testresults t2
WHERE t2.TestID <= t1.TestID AND t2.TesttableID = 1 ) AS Resttime FROM Testresults t1 WHERE t1.TesttableID = 1
during a group project we recent sent out a survey regarding the site we're building. I've put the data into a mysql database and i'm trying to figure out how to count how many times certain scores was given in each category
the table looks like this
+-----------------+--------------+-------------------+
| Design | Ease of use | Responsiveness |
+-----------------+--------------+-------------------+
| 5 | 5 | 5
| 4 | 4 | 4
| 3 | 3 | 3
| 2 | 2 | 2
| 1 | 1 | 1
| 5 | 4 | 2
| 5 | 4 | 4
| 3 | 3 | 3
| 1 | 2 | 2
| 1 | 2 | 2
I've found a query that works for one colum
SELECT Design, COUNT(*) AS num FROM table GROUP BY Design
I would then get
Design | num
-------------
5 | 3
4 | 1
3 | 2
2 | 1
1 | 3
If i were to try
SELECT Design, COUNT(*) AS num1, Ease of use, COUNT(*) as num2 FROM table
GROUP BY Design, Ease of use
The table gets totally messed up.
What I want is to get
Design | num1 | Ease of use | num2 | Responsiveness | num3
------------- --------------------------------------------------
5 | 3 | 5 | 1 | 5 | 1
4 | 1 | 4 | 3 | 4 | 2
3 | 2 | 3 | 2 | 3 | 2
2 | 1 | 2 | 3 | 2 | 4
1 | 3 | 1 | 1 | 1 | 1
Any help would be greatly appreciated
You can unpivot the values and then aggregate. In MySQL, that typically uses union all:
select val, count(*)
from ((select design as val from table) union all
(select ease_of_use from table) union all
(select responsiveness from table
) der
group by val
order by val desc;
For what you want to get, you can do:
select val, sum(design) as design, sum(ease_of_use) as ease_of_use,
sum(responsiveness) as responsiveness
from ((select design as val, 1 as design, 0 as ease_of_use, 0 as responsiveness from table) union all
(select ease_of_use, 0, 1, 0 from table) union all
(select responsiveness, 0, 0, 1 from table
) der
group by val
order by val desc;
I see no reason to repeat the value three times.
Use a synthesized table with the different values, and join this with subqueries that get the counts of each score.
SELECT nums.num AS Design, t1.count AS num1,
nums.num AS `Ease of Use`, t2.count AS num2,
nums.num AS Responsiveness, t3.count AS num3
FROM (SELECT 1 AS num UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) AS nums
LEFT JOIN (
SELECT Design, COUNT(*) AS count
FROM yourTable
GROUP BY Design) AS t1 ON t1.Design = nums.num
LEFT JOIN (
SELECT `Ease of Use`, COUNT(*) AS count
FROM yourTable
GROUP BY `Ease of Use`) AS t2 ON t2.`Ease of Use` = nums.num
LEFT JOIN (
SELECT Responsiveness, COUNT(*) AS count
FROM yourTable
GROUP BY Responsiveness) AS t3 ON t3.Responsiveness = nums.num
DEMO
Here are three ways:
select s.score,
(select count(*) from tbl where `Design` = s.score) as `Design`,
(select count(*) from tbl where `Ease of use` = s.score) as `Ease of use`,
(select count(*) from tbl where `Responsiveness` = s.score) as `Responsiveness`
from (
select Design as score from tbl
union select `Ease of use` from tbl
union select Responsiveness from tbl
) s
order by score desc
http://sqlfiddle.com/#!9/002303/2
select s.score,
(select count(*) from tbl where `Design` = s.score) as `Design`,
(select count(*) from tbl where `Ease of use` = s.score) as `Ease of use`,
(select count(*) from tbl where `Responsiveness` = s.score) as `Responsiveness`
from (select 1 as score union select 2 union select 3 union select 4 union select 5) s
order by score desc
http://sqlfiddle.com/#!9/002303/4
select s.score,
sum(`Design` = score) as `Design`,
sum(`Ease of use` = score) as `Ease of use`,
sum(`Responsiveness` = score) as `Responsiveness`
from (select 1 as score union select 2 union select 3 union select 4 union select 5) s
cross join tbl t
group by s.score
order by s.score desc
http://sqlfiddle.com/#!9/002303/5
They all return the same result:
| score | Design | Ease of use | Responsiveness |
|-------|--------|-------------|----------------|
| 5 | 3 | 1 | 1 |
| 4 | 1 | 3 | 2 |
| 3 | 2 | 2 | 2 |
| 2 | 1 | 3 | 4 |
| 1 | 3 | 1 | 1 |
As #futureweb wrote in the comment, I don't see a reason to repeat the score three times. Though you can if you want using aliases.
If you have millions of rows ;-) and no indexes you would want to get the result with only one table scan. This is possible with:
select
sum(`Design` = 1) as d1,
sum(`Design` = 2) as d2,
sum(`Design` = 3) as d3,
sum(`Design` = 4) as d4,
sum(`Design` = 5) as d5,
sum(`Ease of use` = 1) as e1,
sum(`Ease of use` = 2) as e2,
sum(`Ease of use` = 3) as e3,
sum(`Ease of use` = 4) as e4,
sum(`Ease of use` = 5) as e5,
sum(`Responsiveness` = 1) as r1,
sum(`Responsiveness` = 2) as r2,
sum(`Responsiveness` = 3) as r3,
sum(`Responsiveness` = 4) as r4,
sum(`Responsiveness` = 5) as r5
from tbl
This will return the data you need, but not in the form you'd like:
| d1 | d2 | d3 | d4 | d5 | e1 | e2 | e3 | e4 | e5 | r1 | r2 | r3 | r4 | r5 |
|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|
| 3 | 1 | 2 | 1 | 3 | 1 | 3 | 2 | 3 | 1 | 1 | 4 | 2 | 2 | 1 |
So you would need to post process it.
I have a table which contains data from a radio station, and which songs it played. All the songs played are stored in a table named 'radio_data'. This table looks like this:
-----------------------------------------------
| id | artist_id | song_id | play_date |
| 1 230 420 2017-5-12 12:00 |
| 2 212 971 2017-5-12 12:01 |
| 3 230 420 2017-5-12 13:00 |
| 4 230 420 2017-5-12 15:00 |
| 5 212 971 2017-5-12 15:02 |
-----------------------------------------------
I have a page where some statistics for one specific song is displayed. On this page i would like to show the rank of the song, based on how much it has been played.
Let's say that if i am om the page for song_id 420, it would rank as place 1 out of 2 songs.
I have no idea where to start. I have this query to group the songs:
SELECT COUNT(`id`) AS `playcount`, `artist_id`, `song_id` FROM `radio_data` GROUP BY `song_id` ORDER BY `playcount` DESC
This gives me the following result:
-----------------------------------
| playcount | artist_id | song_id |
| 3 230 420 |
| 2 212 971 |
-----------------------------------
Thanks in advance for your help!
You can use user variables for displaying the rank:
set #rn := 0;
select #rn := #rn + 1 as rank,
song_id,
artist_id,
count(*) as times_played
from your_table
group by song_id, artist_id
order by times_played desc;
If you want to get top, say 10, songs you can add a limit 10 at the end.
SELECT
song_id, count(id) played_times, #rank := #rank +1 rank
FROM
(
songs_plays CROSS JOIN (SELECT #rank := 0)rank
)
GROUP BY song_id
ORDER BY played_times DESC
the result is
+------------+--------------+--------+
| song_id | played_times | rank |
+------------+--------------+--------+
| 420 | 3 | 1 |
| 971 | 2 | 2 |
+------------+--------------+--------+
run it live on SQL fiddle (http://sqlfiddle.com/#!9/1c48d8/5)
I have following table named 'votes', where participant's upvote(1) and downvote(-1) stores. I want to get top 3 voted participant ids and its total votes, where total vote = upvote - downvote. I wrote query as given below but getting error : "Unknown column 'total_votes' in 'IN/ALL/ANY subquery'"
table 'votes'
---------------------------------
| participant_id | vote| voter_id
+------+-------+---------+------+
| 1 | 1 | 1
| 2 | 1 | 1
| 3 | 1 | 1
| 4 | -1 | 1
| 5 | 1 | 1
| 1 | -1 | 2
| 2 | 1 | 2
| 3 | 1 | 2
| 4 | 1 | 2
| 5 | 1 | 2
| 1 | 1 | 3
| 2 | 1 | 3
| 3 | -1 | 3
| 4 | -1 | 3
+------+-------+---------+-----+
SELECT `participant_id`, SUM( `vote` ) AS total_votes FROM `votes`
WHERE total_votes IN
(SELECT total_votes FROM
(SELECT DISTINCT (SUM( vote )) AS total_votes FROM `votes` GROUP BY `participant_id`
ORDER BY `total_votes` DESC LIMIT 0 , 3) AS temp )
GROUP BY `participant_id`
Expected result would be
-------------------------------
| participant_id | total_votes
+------+-------+--------+------+
| 2 | 3
| 5 | 2
| 1 | 1
| 3 | 1
+------+-------+--------+------+
You can rewrite your query by using join to get the top participants whose vote score lies in top 3 votes i.e top 3 votes are (3,2,1)
SELECT t.* FROM
(SELECT `participant_id`, SUM( `vote` ) AS total_votes
FROM `votes`
GROUP BY `participant_id`
) t
JOIN (SELECT SUM( `vote` ) AS total_votes FROM `votes`
GROUP BY `participant_id`
ORDER BY `total_votes` DESC LIMIT 0 , 3 ) t1
USING(total_votes)
ORDER BY t.total_votes DESC
Fiddle Demo
What you want to do is following, as there is no total_votes column in your table:
SELECT `participant_id`, SUM( `vote` ) AS total_votes FROM `votes`
WHERE votes IN
(SELECT total_votes FROM
(SELECT DISTINCT (SUM( vote )) AS total_votes FROM `votes` GROUP BY `participant_id`
ORDER BY `total_votes` DESC LIMIT 0 , 3) AS temp )
GROUP BY `participant_id`
Check this simple query:
SELECT
participant_id, total_votes
FROM
(SELECT participant_id,SUM(vote) total_votes
FROM votes
GROUP BY participant_id) a
ORDER BY total_votes DESC
LIMIT 3;
To get all participants for top 3 voting you can use below query:
SELECT
a.participant_id, b.total_votes
FROM
(SELECT participant_id, SUM(vote) total_votes
FROM votes
GROUP BY participant_id) a
JOIN
(SELECT participant_id,SUM(vote) total_votes
FROM votes
GROUP BY participant_id
ORDER BY total_votes DESC LIMIT 3) b
ON a.total_votes=b.total_votes
ORDER BY total_votes DESC;