There's some tricky logic in my latest project (at least for me) and I've been trying to use HAVING
to solve it, but all my plays have incorrect results. p>
I have a linked table that assigns users to user groups and another table that records how many users are in each group so I don't need to count them all the time (the second table is done after user registration updated from time to time).
The problem I have is with the function that updates the numbers in the second table.
The linked table looks like this, and here's the sample data that explains my problem:
+----+---------+----------+ | id | user_id | group_id | +----+---------+----------+ | 1 | 1 | 1 | | 2 | 1 | 5 | | 3 | 14 | 2 | +----+---------+----------+
A user can belong to any number of groups. In fact, in order to be a group, a user must belong to all groups below it. This is because each group is assigned certain permissions. This cannot be changed without a major rewrite of the current application.
What I want to do is count only the highest group for each user, so in the example data above, user 1 will only be counted in group 5, while group 1 will look empty.
Currently, all entries are counted, which means if there are 3 people in group 4, those 3 users are also counted in groups 3, 2, and 1, which makes my numbers relatively Meaningless.
So far I've tried a few variations of:
SELECT user_group_id, COUNT(user_id) members FROM `group_users` GROUP BY user_group_id HAVING count(user_group_id) = 1;
This gives me the same number. Then I tried:
SELECT user_group_id, COUNT(user_id) members FROM `group_users` GROUP BY user_group_id HAVING COUNT(user_id) = 1;
But as I understand now, I'm only asking users who don't appear in any other group.
I feel like I'm on the right track, but I don't know where or what the conditions should be. I've seen some example queries for a similar flow, but all the aliases just add to the confusion.
Can someone point me in the right direction?
You can use aggregation to get the maximum
group_id
for each user and theCOUNT()
window function to count each returned maximumgroup_id
> amount of users:This query filters out all
group_id
that have no members.If you want results for all
group_id
, connect to the above query usingLEFT
of tablegroups
:View a simplified demo.