Reputation: 43
I have following database (small example):
ID | username | action | points
1 | matt | login | 3
2 | john | comment | 6
3 | john | login | 6
4 | peter | login | 8
5 | peter | login | 8
And I am not sure how to select and group usernames which have the same action (=login) and points higher than 5 (for all actions).
Expected results:
username | COUNT | points(SUM)
peter | 2 | 16
I tried subquery, but did not find the right solution. Do you have any idea how to do it? Thank you very much for your help!
Sorry, I did not emphasize the fact, that all actions has to be login
. So, results will be without john
, because there is action comment
related to this username.
Upvotes: 4
Views: 139
Reputation: 1271231
You can do this with an aggregation and a clever having
clause:
select username, sum(points), count(*)
from tbl
group by username
having sum(case when points <= 5 then 1 else 0 end) = 0 and -- count number with points < 5
max(action) = min(action) and -- all the actions are the same and
min(action) = 'login'
Upvotes: 0
Reputation: 8563
try this query
select username, action, sum(points), count(*)
from
tbl
group by username, action
having sum(if (points<=5, 1, 0)) =0 and count(*) >=2
| USERNAME | ACTION | SUM(POINTS) | COUNT(*) |
----------------------------------------------
| peter | login | 16 | 2 |
Upvotes: -1
Reputation: 115660
SELECT username, COUNT(*) AS cnt, SUM(points) AS points
FROM tableX AS t
GROUP BY username
HAVING COUNT(*) = COUNT(CASE WHEN action = 'login' THEN action END)
AND SUM(points) > 5 ;
or:
SELECT username, COUNT(*) AS cnt, SUM(points) AS points
FROM tableX AS t
WHERE action = 'login'
AND NOT EXISTS
( SELECT *
FROM tableX AS tt
WHERE tt.username = t.username
AND ( tt.action <> 'login' OR tt.action IS NULL )
)
GROUP BY username
HAVING SUM(points) > 5 ;
But I think that with an index on (username, login)
and one on (username, points)
, this will be the most efficient:
SELECT username, COUNT(*) AS cnt, SUM(points) AS points
FROM tableX AS t
GROUP BY username
HAVING MIN(action) = 'login'
AND MAX(action) = 'login'
AND SUM(points) > 5 ;
Upvotes: 3