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 (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 ;
source share