[英]count number of rows between rows where value is 1 in mysql
我有以下数据:
client, visit page 2
1,0
2,0
3,1
4,0
5,1
6,0
7,0
8,1
现在我想知道自上次客户访问第 2 页以来有多少客户。所以结果是:
client 3, 3; client 5, 2; client 8,3
最终我只需要出现间隙的次数,所以在这里我将得到一个最终答案:
gap,# occurrences
1,0
2,1
3,2
4,0
这在 mysql 中是否可能,最好没有 for 循环?
数据太大,无法在 python/php 中完全加载。 一种方法是使用 python/php 并选择“访问页面 2”为 1 的所有行,然后使用在 succes n-1 和 succes n 之间的 count(rows) 选择查询执行 for 循环。 但这需要很多时间。
使用@rn
变量创建row_number的效果,并维护变量@lastWas
发生 vp2=1 的先前行号。
交叉连接有助于不必在顶部设置 @rn:= 等内容。 这就是它的唯一目的。
请注意名为inr
的派生表。 即使没有按名称显式使用,所有派生表也需要别名。 可以单独运行派生表的内部结构。 这在开发开始时用于健全性检查,然后在包装它的外部查询中可以忽略其中的几个列。 当然如这里所见。 请参阅答案底部的inr-only以查看该派生表的视图。
create table x
( id int auto_increment primary key,
client int not null,
vp2 int not null
);
insert x(client,vp2) values
(1,0),(2,0),(3,1),(4,0),
(5,1),(6,0),(7,0),(8,1);
select client,rn-lastWas as gap from
( select id,
client,
vp2,
@lastWas as lastWas,
greatest(@rn:=@rn+1,@lastWas:=if(vp2=1,@rn,@lastWas)) as junk, -- forces recalc immediacy inside greatest() function, caring not at all of results
@rn as rn
from x
cross join (select @rn:=0 as r,@lastWas:=0 as l) as blahJunk
order by id
) inr
where vp2=1
+--------+------+
| client | gap |
+--------+------+
| 3 | 3 |
| 5 | 2 |
| 8 | 3 |
+--------+------+
这只是inr
派生表的视图,以帮助可视化上述内容。
+----+--------+-----+---------+------+------+
| id | client | vp2 | lastWas | junk | rn |
+----+--------+-----+---------+------+------+
| 1 | 1 | 0 | 0 | 1 | 1 |
| 2 | 2 | 0 | 0 | 2 | 2 |
| 3 | 3 | 1 | 0 | 3 | 3 |
| 4 | 4 | 0 | 3 | 4 | 4 |
| 5 | 5 | 1 | 3 | 5 | 5 |
| 6 | 6 | 0 | 5 | 6 | 6 |
| 7 | 7 | 0 | 5 | 7 | 7 |
| 8 | 8 | 1 | 5 | 8 | 8 |
+----+--------+-----+---------+------+------+
下面的布朗尼点部分
create table bon
( -- bunch of numbers
i int not null
);
insert bon(i) values (1),(2),(3),(4);
select bon.i as gap,ifnull(qry.rowCount,0) as occurrences
from bon
left join
( select gap,count(*) as rowCount from
( select client,rn-lastWas as gap from
( select id,
client,
vp2,
@lastWas as lastWas,
greatest(@rn:=@rn+1,@lastWas:=if(vp2=1,@rn,@lastWas)) as junk, -- forces recalc
@rn as rn
from x
cross join (select @rn:=0 as r,@lastWas:=0 as l) as blahJunk
order by id
) inr -- derived table alias
where vp2=1
) xxx -- every derived table requires an alias
group by gap
) qry -- derived table alias
on qry.gap=bon.i
+-----+-------------+
| gap | occurrences |
+-----+-------------+
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| 4 | 0 |
+-----+-------------+
一种方法,保持当前的总差距并在每次访问时重置。
select v, count(*) from(
select client,
case when visit = 0 then @v := @v + 1
else @v := @v + 1 end v,
case when visit = 1 then @v := 0 end gap
from table join (select @v := 0) v
order by client
) q
where gap is not null
group by v
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.