Reputation: 1779
I have a user table with id, username and food_id columns. The idea is the users store their favourite food and we come up with a league table of foods. I want to generate a report of the top votes for the each food type. I am using MySQL and PHP.
For clarity, here is an example of the table:
id food_id username
1 1 Bob
2 100 Jane
3 200 Andy
4 1 Maggy
5 100 Rich
6 100 Mick
7 1 Kevin
I have a query that user 'renegm' on Stackoverflow gave me. It give me the results of the food survey. The query is:
select food_id, count(*) score
from myTable
group by food_id
order by score desc limit 100
It gives me the results perfectly as in:
food_id score
1 3
100 4
I realised after I got the answer that I am getting food_ids and not names.
I need to do a join on food table. It looks like
food_id food_name
1 Salad
100 Burgers
How do I incorporate the join into the above query? I have looked at my books but can't quite work it out.
Upvotes: 0
Views: 148
Reputation: 1503
SELECT column_name(s) FROM myTable INNER JOIN food_table ON myTable.food_id=food_table.food_id
will join two tables providing that your table name is is food_table. Adjust the query with desired column names , order and group by
hope it helps
Upvotes: 1
Reputation: 16559
Why dont you do something like the following which uses triggers to maintain the ratings so all you need to do is a very simple query to get the result you want:
This method will be much more performant as your tables grow.
Hope it helps
Example query
select * from food order by rating desc;
+---------+--------+-----------+-------------+--------+
| food_id | name | num_votes | total_score | rating |
+---------+--------+-----------+-------------+--------+
| 1 | food 1 | 6 | 19 | 3.17 |
| 3 | food 3 | 2 | 6 | 3.00 |
| 2 | food 2 | 3 | 7 | 2.33 |
+---------+--------+-----------+-------------+--------+
3 rows in set (0.00 sec)
full script
drop table if exists food;
create table food
(
food_id int unsigned not null auto_increment primary key,
name varchar(255) not null,
num_votes int unsigned not null default 0,
total_score int unsigned not null default 0,
rating decimal(8,2) not null default 0
)
engine = innodb;
drop table if exists food_vote;
create table food_vote
(
food_id int unsigned not null,
user_id int unsigned not null,
score tinyint unsigned not null default 0,
primary key (food_id, user_id)
)
engine=innodb;
delimiter #
create trigger food_vote_after_ins_trig after insert on food_vote
for each row
begin
update food set
num_votes = num_votes + 1,
total_score = total_score + new.score,
rating = total_score / num_votes
where
food_id = new.food_id;
end#
delimiter ;
insert into food (name) values ('food 1'),('food 2'), ('food 3');
insert into food_vote (food_id, user_id, score) values
(1,1,5),(1,2,4),(1,3,3),(1,4,2),(1,5,1),(1,6,4),
(2,1,2),(2,2,1),(2,3,4),
(3,1,4),(3,5,2);
Upvotes: 2
Reputation: 8036
select
(SELECT food_name from food_table food where food.id = mt.food_id) foodName,
count(*) score
from myTable mt
group by food_id
order by score desc limit 100
Upvotes: 1
Reputation: 212412
select f.food_id,
n.food_name,
count(f.food_id) score
from myTable
left join food_names n
on n.food_id = f.food_id
group by f.food_id,
n.food_name
order by score desc limit 100
Upvotes: 2
Reputation: 1332
Here you go:
select myTable.food_id, food.food_name, count(myTable.id) score from myTable join food on (food.food_id = myTable.food_id) group by myTable.food_id order by myTable.score desc limit 100
Upvotes: 1