Php 计算连续访问的次数
每次登录用户访问网站时,他们的数据都会放入包含用户ID和日期的表中(每个用户每天一行或零行): 当我从主用户表中提取用户数据时,我需要随时访问连续访问的次数。。对于这个用户,它应该是4 目前,我正在通过主用户表中的非规范化Php 计算连续访问的次数,php,mysql,sql,Php,Mysql,Sql,每次登录用户访问网站时,他们的数据都会放入包含用户ID和日期的表中(每个用户每天一行或零行): 当我从主用户表中提取用户数据时,我需要随时访问连续访问的次数。。对于这个用户,它应该是4 目前,我正在通过主用户表中的非规范化连续访问计数器执行此操作,但由于未知原因,它有时会重置。。我想尝试一种只使用上表中数据的方法 获取该数字(上例中为4)的最佳SQL查询是什么?有数百名用户访问,我们每天有数百万注册用户和点击率 编辑:根据下面的评论,我正在发布我当前用于执行此操作的代码;然而,它有一个问题,它有
连续访问
计数器执行此操作,但由于未知原因,它有时会重置。。我想尝试一种只使用上表中数据的方法
获取该数字(上例中为4)的最佳SQL查询是什么?有数百名用户访问,我们每天有数百万注册用户和点击率
编辑:根据下面的评论,我正在发布我当前用于执行此操作的代码;然而,它有一个问题,它有时会无缘无故地重置,而且它也会在周末为每个人重置它,很可能是因为DST更改
// Called every page load for logged in users
public static function OnVisit($user)
{
$lastVisit = $user->GetLastVisit(); /* Timestamp; db server is on the same timezone as www server */
if(!$lastVisit)
$delta = 2;
else
{
$today = date('Y/m/d');
if(date('Y/m/d', $lastVisit) == $today)
$delta = 0;
else if(date('Y/m/d', $lastVisit + (24 * 60 * 60)) == $today)
$delta = 1;
else
$delta = 2;
}
if(!$delta)
return;
$visits = $user->GetConsecutiveVisits();
$userId = $user->GetId();
/* NOTE: t_dailyvisit is the table I pasted above. The table is unused;
* I added it only to ensure that the counter sometimes really resets
* even if the user visits the website, and I could confirm that. */
q_Query("INSERT IGNORE INTO `t_dailyvisit` (`user`, `date`) VALUES ($userId, CURDATE())", DB_DATABASE_COMMON);
/* User skipped 1 or more days.. */
if($delta > 1)
$visits = 1;
else if($delta == 1)
$visits += 1;
q_Query("UPDATE `t_user` SET `consecutivevisits` = $visits, `lastvisit` = CURDATE(), `nvotesday` = 0 WHERE `id` = $userId", DB_DATABASE_COMMON);
$user->ForceCacheExpire();
}
如果没有必要记录用户登录webiste的每一天,而您只想知道他连续登录的天数,我更喜欢这种方式: 选择3列:LastVisite(日期)、ConcertiveDays(整数)和User 登录时,检查用户的条目,确定上次访问是否为“今日-1”,然后在“连续日”列中添加1,并在“上次访问”列中存储“今日”。如果最后一个vist大于“今天-1”,则在连续几天内存储1
HTH如果不需要记录用户登录webiste的每一天,而您只想知道他连续登录的天数,我更喜欢这种方式: 选择3列:LastVisite(日期)、ConcertiveDays(整数)和User 登录时,检查用户的条目,确定上次访问是否为“今日-1”,然后在“连续日”列中添加1,并在“上次访问”列中存储“今日”。如果最后一个vist大于“今天-1”,则在连续几天内存储1
HTH我错过了mysql标签,写了这个解决方案。遗憾的是,这在MySQL中不起作用,因为它不支持窗口功能 不管怎样,我还是把它贴了出来,因为我为此付出了一些努力。用PostgreSQL测试。与Oracle或SQL Server(或任何其他支持窗口功能的像样RDBMS)类似 测试设置 简单版本 输出:
id | max_consecutive_days
--------+----------------------
444631 | 4
更快/更短
后来我找到了一个更好的方法<代码>grp数字不是连续的(而是不断上升的)。没关系,因为这些只是达到目的的手段:
SELECT id, max(dur) + 1 AS max_consecutive_days
FROM (
SELECT id, grp, max(visit) - min(visit) AS dur
FROM (
-- subtract an integer representing the number of day from the row_number()
-- creates a "group number" (grp) for consecutive days
SELECT id
,EXTRACT(epoch from visit)::int / 86400
- row_number() OVER (PARTITION BY id ORDER BY visit) AS grp
,visit
FROM v
ORDER BY 1,2
) x
GROUP BY 1,2
) y
GROUP BY 1
ORDER BY 1
LIMIT 1;
更多
- 类似问题的解决方案。
您可能能够在MySQL中实现类似的功能 - 关于dba.SE的密切相关的答案,并有详细的解释和说明李>
- 依此类推:
id | max_consecutive_days
--------+----------------------
444631 | 4
更快/更短
后来我找到了一个更好的方法<代码>grp数字不是连续的(而是不断上升的)。没关系,因为这些只是达到目的的手段:
SELECT id, max(dur) + 1 AS max_consecutive_days
FROM (
SELECT id, grp, max(visit) - min(visit) AS dur
FROM (
-- subtract an integer representing the number of day from the row_number()
-- creates a "group number" (grp) for consecutive days
SELECT id
,EXTRACT(epoch from visit)::int / 86400
- row_number() OVER (PARTITION BY id ORDER BY visit) AS grp
,visit
FROM v
ORDER BY 1,2
) x
GROUP BY 1,2
) y
GROUP BY 1
ORDER BY 1
LIMIT 1;
更多
- 类似问题的解决方案。
您可能能够在MySQL中实现类似的功能 - 关于dba.SE的密切相关的答案,并有详细的解释和说明李>
- 依此类推:
SELECT id, max(dur) + 1 AS max_consecutive_days
FROM (
SELECT id, grp, max(visit) - min(visit) AS dur
FROM (
-- subtract an integer representing the number of day from the row_number()
-- creates a "group number" (grp) for consecutive days
SELECT id
,EXTRACT(epoch from visit)::int / 86400
- row_number() OVER (PARTITION BY id ORDER BY visit) AS grp
,visit
FROM v
ORDER BY 1,2
) x
GROUP BY 1,2
) y
GROUP BY 1
ORDER BY 1
LIMIT 1;