I have a database on sporting events whose schema can be summarized like this:
Teams
--------
id
name
Events
-------
id
nickname
date
team_1 (links to teams.id)
team_2 (links to teams.id)
Plays
-----
id
event (links to events.id)
<other details>
I want to say things like, "For each event after such and such date, give me the nickname, the date, the names of the two teams, and the number of plays recorded." My attempt looks like this:
SELECT COUNT(plays), events.nickname, events.start, team1.name, team2.name
FROM plays
JOIN events ON plays.event = events.id
JOIN teams AS team1 ON events.team_1 = team1.id
JOIN teams AS team2 ON events.team_2 = team2.id
WHERE events.start > '2023-02-01'
GROUP BY events.id
But it tells me:
error: column "team1.name" must appear in the GROUP BY clause or be
used in an aggregate function
I have seen this error in cases where it would be truly illogical, where the aggregation produces less records than the rest of the query. But that is not true in this case. So what is the correct syntax for asking this query?
3
Answers
What I would suggest is the below. This used a
DERIVED TABLE
(T3) to get you a count for every event. This keeps the group by separate from your main query.T3.PlaysCount
will showNULL
if there are no plays. To get around this you can do,COALESCE(T3.PlaysCount, 0)
which will show0
instead ofNULL
.Additionally, if you don’t want to show events with 0 plays, change the
LEFT JOIN
to aJOIN
All column in the output of group by should be either part of group by condition or a aggregated column. I guess those columns are identified with respect to events.id. so you can simply use max() function to pick of the value out. see the following code as an example:
as the error message already said, all column in the
SELECT
must appear in theGROUP BY
or use aggregation functionsBut in your case it is isimle, as every column is unique and has no duplictaes for every eventid