我有以下数据:
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,然后使用带有成功n-1和成功n之间的count(行)的select查询执行for循环。但这需要很长时间。
答案 0 :(得分:1)
使用@rn
变量创建 row_number 的效果,并维护变量@lastWas
中发生vp2 = 1的前一行号。
交叉连接有助于不必在顶部设置@rn:= etc。这就是它的唯一目的。
请注意名为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 |
+--------+------+
Advanced Mysql User Variable Techniques
这是仅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 |
+-----+-------------+
答案 1 :(得分: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
;