Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get consecutive records in mysql

Tags:

php

mysql

I have table structure as following

ID           user_id         win 
1              1               1 
2              1               1 
3              1               0 
4              1               1 
5              2               1 
6              2               0 
7              2               0 
8              2               1 
9              1               0 
10             1               1 
11             1               1 
12             1               1 
13             1               1
14             3               1 

I wants to get consecutive wins(win=1) for each users in mysql.like for user_id=1, it should return 4(record id 10,11,12,13), for user_id=2(record id=5), it should return 1.

I can do that in php after retriving record for each user but I don't know how I can do it using query to mysql.

Also what would be better in term of performance, using php or mysql. Any help will be appreciated.Thanks!!!

like image 447
Ram Avatar asked Sep 12 '12 21:09

Ram


People also ask

How do you find consecutive data in SQL?

Begin by applying the DENSE_RANK function to the rows. To produce the group identifier, we subtract the result of DENSE_RANK from the row value. As the sequence increases, the result of this calculation remains constant but then changes when a new sequence starts. We use this constant to identify the islands.

How do you do consecutive rows in SQL?

For the Tabibitosan method, assign each row an increasing number, ordered by the run date. When you subtract this from the run_date, consecutive rows have the same result.

How do I find Rowcount in SQL?

Use the COUNT aggregate function to count the number of rows in a table. This function takes the name of the column as its argument (e.g., id ) and returns the number of rows for this particular column in the table (e.g., 5).


2 Answers

Inner query counts each streak. Outer query gets the max per user. Query is untested (but based on one that works)

set @user_id = null;
set @streak = 1;

select user_id, max(streak) from (
  SELECT user_id, streak,
    case when @user_id is null OR @user_id != user_id then @streak := 1 else @streak := @streak + 1 end as streak_formula,
    @user_id := user_id,
    @streak as streak
  FROM my_table
) foo
group by user_id
like image 91
Alain Collins Avatar answered Sep 25 '22 00:09

Alain Collins


Not sure if you've managed to get the other query to work but here's my attempt, definetly working - Sqlfiddle to prove it.

set @x=null;
set @y=0;

select sub.user_id as user_id,max(sub.streak) as streak
from
(
select 
case when @x is null then @x:=user_id end,
case 
when win=1 and @x=user_id then @y:=@y+1 
when win=0 and @x=user_id then @y:=0 
when win=1 and @x<>user_id then @y:=1
when win=0 and @x<>user_id then @y:=0
end as streak,
@x:=user_id as user_id
from your_table
) as sub
group by sub.user_id

How to get it to work on a PHP page and testing to see you're getting the right results is underneath, I have also optimized the query a bit:

mysql_query("set @y=0");
$query=mysql_query("select sub.user_id as user_id,max(sub.streak) as streak
from
(
select
case 
when win=1 and @x=user_id then @y:=@y+1 
when win=0 and @x=user_id then @y:=0 
when win=1 and @x<>user_id then @y:=1
when win=0 and @x<>user_id then @y:=0
end as streak,
@x:=user_id as user_id
from your_table
) as sub
group by sub.user_id");
while($row=mysql_fetch_assoc($query)){
print_r($row);}
like image 36
mrmryb Avatar answered Sep 23 '22 00:09

mrmryb