检测列值的变化?

时间:2013-07-22 14:38:54

标签: php mysql group-by

这就是我的表格外观

page  time
x      0
x      1
x      2
y      0
y      1
x      0
x      1
x      2
x      3 
z      0
z      1
z      2
z      3

我正在根据x,y,z的值绘制图表。

所以我的图表看起来像 -

enter image description here

每个条形的高度由各页的峰值决定。

我试过这样的事情

`$query="select `page`,`time` from `table` where session_id="$session_id" GroupBy ...how do i go about this.";

但它只给了我3个酒吧。但我想要的不是。 bar取决于开关(从峰值切换到0.在上表中有4个这样的开关,因此我的图中有4个条。)

我希望我对自己的问题很清楚。 我无法弄清楚查询。

UPDATE - &GT; 我正在开发一个跟踪器,它基本上跟踪用户点击的所有链接和时间花在它上。所以开关可以是从X到Y到X到Z ..它可以是随机的。这就是为什么我很困惑。< / p>

更新2: 假设当我已经在同一页面上花费时间== 2时,我点击了一个将我重定向到第x页的链接...那么只返回最大(时间),我需要X上的前一个最大时间 + 当前X上的最长时间。 简单来说,如果我再次访问同一页面...我不希望最后记录的时间被抑制,如果花费更多的时间在它上面比较,而不是我想加起来时间..

2 个答案:

答案 0 :(得分:4)

问题是,您希望根据列的特定顺序进行分组,而不是列页。

这是一种解决方法:

CREATE TABLE Table1
    (id int auto_increment, `page` varchar(1), `time` int, primary key (id))
;

INSERT INTO Table1
    (`page`, `time`)
VALUES
    ('x', 0),
    ('x', 1),
    ('x', 2),
    ('y', 0),
    ('y', 1),
    ('x', 0),
    ('x', 1),
    ('x', 2),
    ('x', 3),
    ('z', 0),
    ('z', 1),
    ('z', 2),
    ('z', 3)
;


select page, max(time) from (
select 
t.*
, IF(@prev != page, @counter := @counter + 1, @counter) as my_groups
, @prev:=page
from
Table1 t
, (select @prev:=NULL, @counter:=0) v 
order by id
) sq
group by my_groups

看到它正常工作here in an sqlfiddle

请注意,我引入了专栏id。它只是一个有助于保证订单的专栏。在数据库中没有第一行或最后一行。只需从表中选择,插入行的顺序就不是保证顺序。

Explanatation:

这里

Table1 t
, (select @prev:=NULL, @counter:=0) v 

我们在查询中初始化变量。它和写作一样

SET @prev:=NULL;
SET @counter:=0;
SELECT ... FROM Table1 ORDER BY whatever...

现在在子查询的SELECT部分​​

, IF(@prev != page, @counter := @counter + 1, @counter) as my_groups
, @prev:=page

这两行在编写顺序中很重要。第二行将读取行的值分配给变量@prev。在第一行中,我们检查@prev是否与SELECT读取的行不同。如果是,我们将计数器变量@counter增加1,如果不是我们保持不变。

子查询(稍微修改以使其更清楚会发生什么)

select 
IF(@prev != page, @counter := @counter + 1, @counter) as my_groups
, page
, @prev
, @prev:=page
, time
from
Table1 t
, (select @prev:=NULL, @counter:=0) v
order by id

然后返回此结果:

| MY_GROUPS | PAGE |  @PREV | @PREV:=PAGE | TIME |
--------------------------------------------------
|         0 |    x | (null) |           x |    0 |
|         0 |    x |      x |           x |    1 |
|         0 |    x |      x |           x |    2 |
|         1 |    y |      x |           y |    0 |
|         1 |    y |      y |           y |    1 |
|         2 |    x |      y |           x |    0 |
|         2 |    x |      x |           x |    1 |
|         2 |    x |      x |           x |    2 |
|         2 |    x |      x |           x |    3 |
|         3 |    z |      x |           z |    0 |
|         3 |    z |      z |           z |    1 |
|         3 |    z |      z |           z |    2 |
|         3 |    z |      z |           z |    3 |

外部查询很简单。我们按列my_groups进行分组(我们将此行别名)

IF(@prev != page, @counter := @counter + 1, @counter) as my_groups

并且对于每个组,我们返回页面和最长时间。

希望现在一切都清楚了。但是,如果情况并非如此,请随意询问:)

答案 1 :(得分:-1)

你可以这样做:

select page, max(time) from table where session_id = ...
group by page

但根据上面的表结构,它只会给出3个值,因为第1和第3个x将被视为相同。这是因为您的表的定义方式。所以你会得到3张图而不是4张。