4

我有以下数据库(小例子):

ID | username | action  | points
1  | matt     | login   | 3
2  | john     | comment | 6
3  | john     | login   | 6
4  | peter    | login   | 8
5  | peter    | login   | 8

而且我不确定如何选择和分组具有相同操作(=登录)且点数高于 5(对于所有操作)的用户名。

预期成绩:

username | COUNT | points(SUM)
peter    | 2     | 16

我尝试了子查询,但没有找到正确的解决方案。你知道怎么做吗?非常感谢您的帮助!

抱歉,我没有强调所有行为都必须是login. 因此,结果将没有john,因为有comment与此用户名相关的操作。

4

3 回答 3

3
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 ;

或者:

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 ;

但我认为,如果有一个索引 on(username, login)和一个 on (username, points),这将是最有效的:

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 ;
于 2013-05-24T12:09:49.117 回答
0

您可以使用聚合和聪明的having子句来做到这一点:

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'
于 2013-05-24T11:56:36.633 回答
-1

试试这个查询

select username, action, sum(points), count(*) 
from 
tbl
group by username, action 
having sum(if (points<=5, 1, 0)) =0  and count(*) >=2

SQL 小提琴

| USERNAME | ACTION | SUM(POINTS) | COUNT(*) |
----------------------------------------------
|    peter |  login |          16 |        2 |
于 2013-05-24T11:44:59.103 回答