sql记录检索

c0vxltue  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(338)

大家好,
我需要帮助从mysql表中检索记录,如下所示。请注意我的目标结果:

下面是我目前的方法,它可以很好地处理少量的行,但是非常慢,或者在数千行甚至数百行上花费时间。

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;
}

当月:

public function userTopRecruitsCurrMonth(){
    $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)->where('signup_date', '>=', 'startDateOfCurrentMonth')->count();

            if($refCnts > 0){
                $tempUID['userAffID'] = $value->aff_id;
                $tempUID['userRecruits'] = $refCnts;
                $mainAssocArr[] = $tempUID;
            }
        }
    }//End of For loop

    foreach ($mainAssocArr as $key => $row) {
        $volume[$key]  = $row['userRecruits'];
        $edition[$key] = $row['userAffID'];
    }

    array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $mainAssocArr);

    return $mainAssocArr;
}

如有任何帮助或建议,将不胜感激。
注:我使用的是雄辩的模型,但不是“拉威尔”

bmp9r5qi

bmp9r5qi1#

从您的评论中,我了解到为您提供sql查询可能会有所帮助。
这个简单的加总查询将返回 REFERRAL 出现次数最多(所有时间),最高在顶部。

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
cs7cruho

cs7cruho2#

我将使用如下查询:

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\u id所在的实际用户的数据。这将给你的东西,如他们的名字等,如果你没有再次加入你不会得到这些东西。
它还构建了一个更小的temp(内存中)表,如果您在同一级别上执行它(可能的话,我将不得不用explain more深入研究它)。
你自己试试
如果您只想做一个月,我们可以修改子查询,只统计当月添加的用户数:

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

最后,如果您希望用户没有引用任何人,您可能/将不得不使用左连接。
例如
如果你加上

WHERE
  u2.agg IS 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

D小提琴
现在是0了
我发现 COALESCE 为了非常有用,代码中的工作越少,事情就越容易。如果您可以按照您希望的方式从数据库格式化数据,那么通常情况下,它比后面的操作要好。这可能是使用 fetchAll 在使用它之前,必须循环使用它并在php中修改它。
干杯!

相关问题