我正在寻找一种有效的方式来追踪回头客。
到目前为止我选择的选项列表:
我认为最后一个选项效率最高,因为我不需要创建单独的日志记录表。
然而,记录表似乎更准确,周期性,对吧?
更新
准确性仍然具有优先权,所以我选择了第一个选项,以及PHP中的一些逻辑。
我选择存储每周登录次数(年度),例如:201433
。
问题:关于PHP代码,有没有办法将两个查询结合起来,省去嵌套循环(效率)?
数据库表:
+----+--------+--------+-----------+
| id | userId | logins | year_week |
+----+--------+--------+-----------+
| 1 | 1 | 4 | 201432 |
| 2 | 1 | 3 | 201433 |
| 3 | 2 | 2 | 201433 |
+----+--------+--------+-----------+
查询:
SELECT
userId,
SUM(logins) as total
FROM
User_Logins
GROUP BY
userId
ORDER BY
userId
-----------
// get first year_week
SELECT
userId,
year_week
FROM
User_Logins
GROUP BY
userId
ORDER BY
userId
查询结果:
+--------+-------+
| userId | total |
+--------+-------+
| 1 | 7 |
| 2 | 2 |
+--------+-------+
+--------+-----------+
| userId | year_week |
+--------+-----------+
| 1 | 201432 |
| 2 | 201433 |
+--------+-----------+
PHP代码:
$returningUsers = 0;
$userLogins = $this->model->firstQuery();
$userLoginWeeks = $this->model->secondQuery();
$today = new DateTime();
function weeksPassed($today, $year, $week)
{
$today->setISODate($today->format('Y'), $today->format('W'));
// year and week from user first login
$yearWeek = new DateTime();
$yearWeek->setISODate($year, $week);
$daysPassed = $today->diff($yearWeek)->days;
$weeksPassed = $daysPassed / 7;
return $weeksPassed;
}
if ($userLogins && $userLoginWeeks)
{
foreach ($userLoginWeeks as $userLoginWeek)
{
$userId = $userLoginWeek->userId;
$year_week = $userLoginWeek->year_week;
$year = (int) substr($year_week, 0, 4);
$week = (int) substr($year_week, 4);
$weeksPassed = weeksPassed($today, $year, $week);
$totalLogins = 0;
// Look up user logins from other query
foreach ($userLogins as $logins)
{
if ($logins->userId == $userId)
{
$totalLogins = $logins->total;
break;
}
}
$avgLogins = $totalLogins;
// Average calculated over weeks that have passed since first login
if ($weeksPassed > 0)
{
$avgLogins = $totalLogins / $weeksPassed;
}
// if average >= 1 per week => returning user
if ($avgLogins >= 1)
{
$returningUsers++;
}
}
}
return $returningUsers;