以下查询中的计数应为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)
答案 0 :(得分:2)
为什么计数为3和1?您的查询分组:
有两个行,其中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