连续非空值的计数

时间:2009-08-24 10:48:34

标签: mysql count group-by

以下查询中的计数应为3和1。计数应该是连续获得的积分。因此,一旦用户未能获得任何积分,计数将重新开始。

mysql> select name, count(*) from sortest group by name, (points = 0) OR (points is NULL)  having name= 'john';
+------+----------+
| name | count(*) |
+------+----------+
| john |        4 |
| john |        2 |
+------+----------+
2 rows in set (0.00 sec)

mysql> select * from sortest;
+----+------+--------+
| id | name | points |
+----+------+--------+
|  1 | john |     12 |
|  2 | john |     23 |
|  3 | john |     43 |
|  4 | hari |   NULL |
|  5 | hari |     56 |
|  6 | john |   NULL |
|  7 | hari |      0 |
|  8 | john |     44 |
|  9 | john |      0 |
| 10 | hari |     43 |
| 11 | hari |     44 |
| 12 | hari |     78 |
| 13 | hari |      0 |
+----+------+--------+
13 rows in set (0.00 sec)

mysql> show create table sortest\G
*************************** 1. row ***************************
       Table: sortest
Create Table: CREATE TABLE `sortest` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) default NULL,
  `points` int(11) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

在这种情况下,约翰的计数应为5,1和2

5和1因为它以0或NULL和2结尾,因为它还没有用0或NULL关闭

mysql> select * from sortest;
+----+------+--------+
| id | name | points |
+----+------+--------+
|  1 | john |     12 |
|  2 | john |     23 |
|  3 | john |     43 |
|  4 | hari |   NULL |
|  5 | hari |     56 |
|  6 | john |   NULL |
|  7 | hari |      0 |
|  8 | john |     44 |
|  9 | john |      0 |
| 10 | hari |     43 |
| 11 | hari |     44 |
| 12 | hari |     78 |
| 13 | hari |      0 |
| 14 | john |     55 |
| 15 | john |     95 |
+----+------+--------+
15 rows in set (0.00 sec)

mysql> select name, count(*) from sortest group by name, (points = 0) OR (points is NULL)  having name= 'john';
+------+----------+
| name | count(*) |
+------+----------+
| john |        6 |
| john |        2 |
+------+----------+
2 rows in set (0.00 sec)

3 个答案:

答案 0 :(得分:2)

为什么计数为3和1?您的查询分组:

  1. 名称
  2. (points = 0 OR points is NULL)
  3. 有两个行,其中name=john(points = 0 OR points IS NULL)以及四个其他行name=john

    因此,您的查询正如您所描述的那样工作。你最终想要完成的是什么?

答案 1 :(得分:1)

首先,你所要求的是一点不合理。你看,没有order by条款就没有顺序的顺序。但是,我的假设是,您希望获得null行之前的所有内容的计数,按id排序。

其次,这里是:

select
    a.name,
    (select count(*) from sortest where id < a.id and
        id > b.priorId) as count
from
    sortest a
    inner join (select id,
                    (select coalesce(max(id), 0) 
                     from sortest where points is null and id < s1.id) as priorId
                from sortest s1 where points is null
                union
                select max(id) as id,
                    (select coalesce(max(id), 0) 
                     from sortest where points is null and id < s1.id) as priorId
                from sortest s2group by name) b on
        a.id = b.id

它有点混乱和令人费解,但它会让你得到你想要的东西。

答案 2 :(得分:1)

选择最大连胜纪录:

SELECT  name, MAX(cnt)
FROM    (
        SELECT  name, COUNT(*) AS cnt
        FROM    (
                SELECT  sortest.*,
                        @r := @r + ((COALESCE(@name, name) <> name) OR (COALESCE(points, 0) = 0)) AS series,
                        @name := name
                FROM    (
                        SELECT  @name := NULL,
                                @r := 0
                        ) vars, sortest
                ORDER BY
                        name, id
                ) q
        WHERE   points > 0
        GROUP BY
                name, series
        ) q2
GROUP BY
        name

选择所有获胜条纹:

SELECT  name, COUNT(*) AS cnt
FROM    (
        SELECT  sortest.*,
                @r := @r + ((COALESCE(@name, name) <> name) OR (COALESCE(points, 0) = 0)) AS series,
                @name := name
        FROM    (
                SELECT  @name := NULL,
                        @r := 0
                ) vars, sortest
        ORDER BY
                name, id
        ) q
WHERE   points > 0
GROUP BY
        name, series