Reputation: 394
My table called matchEvent looks like this:
eventId playerId matchId eventName description
--------------------------------------------------------
100 50 1 goal freeKick
100 50 1 goal shot
200 50 2 foul penalty
300 51 3 goal header
300 51 3 goal ownGoal
400 51 4 goal ownGoal
400 51 4 goal shot
I want to count all regular goals (but not own goals) scored by a specific player in a specific match. I tried:
con = sqlite3.connect(my_db)
regular_goals = con.execute("SELECT playerId, matchId, COUNT(DISTINCT eventId) FROM matchEvent WHERE eventName = 'goal' GROUP BY playerId, matchId HAVING description <> 'ownGoal'").fetchall()
The problem is that HAVING clause seems to be filtering the groups based on group's top row value so it's giving me:
[(50, 1, 1),(51, 3, 1)]
while the result I expect is:
[(50, 1, 1)]
since my table contains only one regular goal.
Upvotes: 1
Views: 258
Reputation: 164089
You need 2 levels of aggregation:
SELECT playerId, matchId, SUM(counter) total_goals
FROM (
SELECT playerId, matchId, COUNT(DISTINCT eventId) counter
FROM matchEvent
GROUP BY eventId, playerId, matchId
HAVING SUM(eventName = 'goal') > 0 AND SUM(description = 'ownGoal') = 0
) t
GROUP BY playerId, matchId
See the demo.
Or:
SELECT playerId, matchId, COUNT(*) total_goals
FROM (
SELECT playerId, matchId
FROM matchEvent
GROUP BY eventId, playerId, matchId
HAVING SUM(eventName = 'goal') > 0 AND SUM(description = 'ownGoal') = 0
) t
GROUP BY playerId, matchId
See the demo.
Or:
SELECT playerId, matchId, COUNT(DISTINCT eventId) total_goals
FROM matchEvent
WHERE eventName = 'goal'
AND eventId NOT IN (SELECT eventId FROM matchEvent WHERE description = 'ownGoal')
GROUP BY playerId, matchId
See the demo.
Results:
| playerId | matchId | counter |
| -------- | ------- | ------- |
| 50 | 1 | 1 |
Upvotes: 1