Reputation: 1293
This is a select statement that calculates the average rating of a song in my database
SELECT *, (tab.rating_sum/tab.rating_count) as rating_average FROM
(SELECT song_id, COUNT(rating) rating_count, SUM(rating) rating_sum FROM ratings
GROUP BY song_id) tab
INNER JOIN SONGS WHERE SONGS.id = tab.song_id
I need to insert the column rating_average from the table RATINGS into the table SONGS when a new rating is inserted in RATINGS. I also need to make sure it goes into the proper song_id column. How can I do this with a trigger? I have been ripping my hair out.
This is the best that I can come up with, but I have no idea what I am doing with triggers:
CREATE TRIGGER rating_trig ON ratings FOR INSERT AS
BEGIN
UPDATE SONGS SET
rating = SELECT (tab.rating_sum/tab.rating_count) as rating_average FROM
(SELECT song_id, COUNT(rating) rating_count, SUM(rating) rating_sum FROM ratings
GROUP BY song_id) tab
INNER JOIN SONGS WHERE SONGS.id = tab.song_id
END
TABLE LAYOUTS:
RATINGS | song_id, rating, username SONGS | id, rating, song_name
Upvotes: 4
Views: 6621
Reputation: 8395
Assuming a table structure like this one:
use test;
create table song(
song_id integer,
rating_avg double,
rating_sum integer,
rating_count integer);
create table rating(
song_id integer,
user_id integer,
rating integer);
Define the following triggers:
delimiter $$
create trigger bi_song before insert on test.song
for each row
begin
set NEW.rating_sum = 0;
set NEW.rating_count = 0;
set NEW.rating_avg = NULL;
end
$$
create trigger ai_rating after insert on test.rating
for each row
begin
update song set
rating_sum = rating_sum + NEW.rating,
rating_count = rating_count + 1,
rating_avg = rating_sum / rating_count
where song_id = NEW.song_id;
end
$$
delimiter ;
And it should work like this:
mysql> insert into song(song_id) values (1);
Query OK, 1 row affected (0.06 sec)
mysql> select * from song;
+---------+------------+------------+--------------+
| song_id | rating_avg | rating_sum | rating_count |
+---------+------------+------------+--------------+
| 1 | NULL | 0 | 0 |
+---------+------------+------------+--------------+
1 row in set (0.00 sec)
mysql> insert into rating(song_id, user_id, rating) values (1, 1000, 5);
Query OK, 1 row affected (0.05 sec)
mysql> select * from song;
+---------+------------+------------+--------------+
| song_id | rating_avg | rating_sum | rating_count |
+---------+------------+------------+--------------+
| 1 | 5 | 5 | 1 |
+---------+------------+------------+--------------+
1 row in set (0.00 sec)
mysql> insert into rating(song_id, user_id, rating) values (1, 1001, 7);
Query OK, 1 row affected (0.05 sec)
mysql> select * from song;
+---------+------------+------------+--------------+
| song_id | rating_avg | rating_sum | rating_count |
+---------+------------+------------+--------------+
| 1 | 6 | 12 | 2 |
+---------+------------+------------+--------------+
1 row in set (0.00 sec)
This is very simplified, just to illustrate how to work with triggers. In a real application, you would have more columns, indexes, etc.
Upvotes: 6