我有一张带有ip的表和一个查看日期,以及一个有网站ID的网站
+------------+-----------+---------------------+
| website_id | ip | view_date |
+------------+-----------+---------------------+
| 123 | 123123123 | 2014-01-01 10:23:00 |
+------------+-----------+---------------------+
| 123 | 987987987 | 2014-01-01 10:23:00 |
+------------+-----------+---------------------+
| 123 | 123123123 | 2014-01-01 10:26:00 |
+------------+-----------+---------------------+
| 123 | 987987987 | 2014-01-01 10:24:00 |
+------------+-----------+---------------------+
| 123 | 987987987 | 2014-01-01 10:25:00 |
+------------+-----------+---------------------+
| 123 | 123123123 | 2014-01-02 03:23:00 |
+------------+-----------+---------------------+
我想从表中获取会话,这是有人在网站上开始直到完成的时间。要查看完成的时间,在查看view_date之后的两个查看日期之一之后,有30分钟或更长时间没有活动。
因此,对于此示例数据,我有2个用户123123123
和987987987
123123123
有2个会话,因为第3行发生在第1行30分钟,第6行发生在第3行后30分钟987987987
有1个会话,因为第4行发生在第2行后不到30分钟,第5行发生在第4行后不到30分钟我不知道如何使用MySQL来计算它。我所知道的是按ip
,然后按view_date
对数据进行排序。之后我迷路了。
当我说会话时我的意思是:
专门用于特定活动的一段时间。
而不是:
一种在多个网页之间跟踪人员的方式。
期望的输出:
+------------+-----------+----------+
| website_id | ip | sessions |
+------------+-----------+----------+
| 123 | 123123123 | 2 |
+------------+-----------+----------+
| 123 | 987987987 | 1 |
+------------+-----------+----------+
答案 0 :(得分:1)
SET @a := null;
SET @b := null;
SET @c := null;
SELECT website_id, ip, view_date, COUNT(counting) as num_sessions
FROM
( SELECT website_id, ip, view_date,
@c := if(@a = ip AND @b BETWEEN view_date - interval 30 minute AND view_date, @c + 1, 1) as counting,
@a := ip, @b := view_date
FROM
( SELECT *
FROM sessions
ORDER BY ip, view_date
)t
)t1
WHERE counting = 1
GROUP BY ip;
答案 1 :(得分:1)
select ip, sum(session) + 1 as session
from (
select
t.*,
if(@previp = ip and timestampdiff(minute, @prevview, view_date) >= 30, 1, 0) as session,
@previp := ip,
@prevview := view_date
from
Table1 t
, (select @prevview := (select view_date from Table1 order by ip, view_date limit 1),
@previp := null) var_init_subquery
order by ip, view_date
) sq
group by ip
答案 2 :(得分:1)
这是我的解决方案
我会计算一下在日期和日期-30分钟之间发生的给定网站ID和IP地址的行数。如果它的0分配1意味着它的新会话,则给它一个0.然后做一个总和。
<强> SQL Fiddle Demo 强>
select website_id,
ip,
sum(newSession) as Sessions
from
(select *,
case
when (select count(*)
from yourTable ytb
where ytb.website_id = yta.website_id
and ytb.ip = yta.ip
and ytb.view_date < yta.view_date
and ytb.view_date > date_add(yta.view_date, INTERVAL -30 MINUTE)) = 0 then 1
else 0
end as newSession
from yourtable yta) baseTable
GROUP BY website_id, ip
答案 3 :(得分:-1)
根据时间和IP排序后,您可以使用游标查找会话总数。您可以从here获取有关mysql游标的更多信息。
更多详情:
CREATE PROCEDURE curdemo()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE i INT;
DECLARE prev_i INT;
DECLARE d DATE;
DECLARE prev_d DATE;
DECLARE cur1 CURSOR FOR SELECT ip, view_date FROM table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
IF prev_i == NULL THEN
FETCH cur1 INTO prev_i, prev_d;
END IF;
FETCH cur1 INTO i, d;
IF done THEN
LEAVE read_loop;
END IF;
IF prev_i == i && INTERVAL_BETWEEN(prev_d, d) > 30min THEN
ADD_IN_SESSIONS_FOR_i ;
END IF;
prev_i = i;
prev_d = d;
END LOOP;
CLOSE cur1;
END;