晚安社区,
我需要帮助来从mysql表中检索记录,如下所示。请注意我的目标结果:
下面是我目前的方法,该方法在行数少的情况下效果很好,但是速度非常慢,或者在成千上万甚至数百行上花费时间。
resolver: lts-9.20
extra-deps: [
repa-3.4.1.4,
]
当月:
public function usersTopRecruits(){
$tempUID = array();
$mainAssocArr = array();
for ($i=0; $i < User::count(); $i++) {
if($i == 0){
$offset = 0;
}
else{
$offset = $this->take * $i;
}
$users = User::take($this->take)->offset($offset)->get();
foreach ($users as $value) {
$refCnts = User::where('referral', $value->aff_id)->count();
if($refCnts > 0){
$tempUID['userAffID'] = $value->aff_id;
$tempUID['userrecruits'] = $refCnts;
$mainAssocArr[] = $tempUID;
}
}
}//End of For loop
//Here, i tried to sort by highest recruits
foreach ($mainAssocArr as $key => $row) {
$desc[$key] = $row['userrecruits'];
$asc[$key] = $row['userAffID'];
}
array_multisort($desc, SORT_DESC, $asc, SORT_ASC, $mainAssocArr);
return $mainAssocArr;
}
任何帮助或建议,将不胜感激。
注意:我使用的是Eloquent模型,但未使用“ laravel”
答案 0 :(得分:2)
根据您的评论,我了解为您提供SQL查询可能会有所帮助。
此简单的综合查询将返回(所有时间)发生次数最多(最高)的REFERRAL
s。
SELECT referral, COUNT(*)
FROM table
GROUP BY referral
ORDER BY COUNT(*) DESC
如果您希望在当月获得相同的结果,则只需添加一个WHERE
子句:
SELECT referral, COUNT(*)
FROM table
WHERE YEAR(sigmup_date) = YEAR(NOW()) AND MONTH(sigmup_date) = MONTH(NOW())
GROUP BY referral
ORDER BY COUNT(*) DESC
答案 1 :(得分:1)
我会使用这样的查询:
SELECT
*
FROM
users AS u0
JOIN
(
SELECT
u1.REFERRAL AS agg,
COUNT(u1.REFERRAL) AS total
FROM
users AS u1
GROUP BY
u1.REFERRAL
ORDER BY total DESC
) AS u2
ON
u2.agg = u0.AFF_ID
通过再次与表联接,子查询允许您提取分组了AFF_ID的实际用户的数据。这将为您提供诸如FIRST_NAME之类的信息。如果您不再次加入,您将不会得到这些东西。
它还会建立一个较小的临时表(在内存中),然后如果您在同一级别上进行操作(可能,我将不得不对其进行深入解释,并进行详细说明)。
如果您只想使用一个月,我们可以修改子查询以仅计算该月添加的用户:
SELECT
*
FROM
users AS u0
JOIN
(
SELECT
u1.REFERRAL AS agg,
COUNT(u1.REFERRAL) AS total
FROM
users AS u1
WHERE
YEAR(u1.sigmup_date) = YEAR(NOW())
AND
MONTH(u1.sigmup_date) = MONTH(NOW())
GROUP BY
u1.REFERRAL
ORDER BY total DESC
) AS u2
ON
u2.agg = u0.AFF_ID
最后,如果您想要未推荐任何人的用户,则可能/将不得不使用LEFT JOIN。
如果您添加
WHERE
u2.agg IS NULL
在外部查询的末尾,您可以找到所有没有引荐的用户。
除了进行任何优化之外,(对我来说)将其作为子查询阅读起来更好。
最后一个,如果您不喜欢NULL,那么可以使用COALESCE()
来解决此问题:
SELECT
u0.*, COALESCE(u2.total,0) AS total
FROM
users AS u0
LEFT JOIN
(
SELECT
u1.REFERRAL AS agg,
COUNT(u1.REFERRAL) AS total
FROM
users AS u1
GROUP BY
u1.REFERRAL
ORDER BY total DESC
) AS u2
ON
u2.agg = u0.AFF_ID
现在这些是0
我发现COALESCE
非常有用,并且您在代码中要做的工作越少,事情就越容易。如果您可以按照所需的方式从数据库中格式化数据,那么通常最好先进行操作。使用fetchAll
之类的东西与必须循环遍历并在PHP甚至无法使用它进行修改之间可能是有区别的。
干杯!