Reputation: 3
I'm trying to make a ratings system. I'm using visual studio. The database has 2 tables, one table for all the music tracks, and another table containing the ratings, and is hooked up with an FK.
Here's my tables and columns http://i.gyazo.com/fc5d042749c8c04fb2b9aa2b64831b0a.png
This is my current attempt and it's giving me an error
SELECT DISTINCT Track.TrackId, SUM(Ratings.rating) AS average, Track.Name, Ratings.trackid
FROM Track
INNER JOIN Ratings
ON Track.TrackId = Ratings.trackid
Msg 8120, Level 16, State 1, Line 1 Column 'Track.TrackId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Upvotes: 0
Views: 669
Reputation: 1269693
If you want to use aggregation functions, then you generally want a group by
. Without the group by
, the query will return only one row.
SELECT t.TrackId, SUM(r.rating) AS average, t.Name
FROM Track t INNER JOIN
Ratings r
ON t.TrackId = r.trackid
GROUP BY t.TrackId, t.name;
In addition, I made the following changes:
distinct
from the select
. This is almost never needed for an aggregation query.Ratings.TrackId
from the select
statement. It is redundant, because it is the same as Track.TrackId
.group by
statement.Upvotes: 0
Reputation: 20014
Every time you are using either a sum, avr, min or max, etc.
functions you have to use Group by that is the law..
What you need to do first is SUM the ratings by track and then joining those later with your track table, something like this:
SELECT T.TrackId, SUM(R.rating) AS average, T.Name
FROM Track T
INNER JOIN
(SELECT TrackId, SUM(Ratings.rating) AS average
FROM Ratings Group By TrackId ) R
ON T.TrackId = r.TrackId
Upvotes: 1
Reputation: 12370
Don't use distinct
. It doesn't do the same thing as Group By
.
In SQL-think, what you're trying to do is group all the rows by Trackid, and average the rating in each group which you do like this:
SELECT Track.TrackId, AVG(1.0000 * Ratings.rating) AS average
FROM Track
JOIN Ratings ON Track.TrackId = Ratings.trackid
Group By Track.TrackId
But, you're also trying to pick up the Name at the same time. Doing that at that same time as a group by isn't as straightforward in SQL as you might wish. A 'correct' way is something like:
SELECT
Track.TrackId,
Average,
Name
FROM Track
INNER JOIN (
SELECT TrackId, AVG(1.0000 * Ratings.rating) AS average
FROM Ratings
Group By TrackId
) R
ON Track.TrackId = R.trackid
Upvotes: 0