Php 在MySql中使用变量计算用户对数值标量的评级

Php 在MySql中使用变量计算用户对数值标量的评级,php,mysql,sql,pdo,Php,Mysql,Sql,Pdo,在我目前工作的网站上,有一个类似于本网站的评级系统,每个客户都可以累积“分数”或“星级” 现在我正在开发一个自动电子邮件系统,它将发送我所有用户的电子邮件 前五名列表及其分数,并与前五名列表并列,还包括收件人用户的个人分数 由于这是servercronjob上的常规任务,因此效率方面非常重要,我使用一个mySql变量来获得每个用户的评级 我想得到另一个用户和他的评分,即使他在100位,使用相同的查询,但由于某种原因,我没有得到正确的结果 工作代码: private function ge

在我目前工作的网站上,有一个类似于本网站的评级系统,每个客户都可以累积“分数”或“星级”

现在我正在开发一个自动电子邮件系统,它将发送我所有用户的电子邮件 前五名列表及其分数,并与前五名列表并列,还包括收件人用户的个人分数

由于这是servercronjob上的常规任务,因此效率方面非常重要,我使用一个mySql变量来获得每个用户的评级

我想得到另一个用户和他的评分,即使他在100位,使用相同的查询,但由于某种原因,我没有得到正确的结果

工作代码:

    private function getTopStars($adminId){
        try{
            $conn = DBLink::getInstance();
            $query = "SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  FROM scores p, (SELECT @rownum:=0) r, users u WHERE u.stars_enabled = 1 and u.user_id=p.user_id and p.admin_id = :admin_id AND u.user_id <> :adminId ORDER BY points DESC";
            $sth = $conn->prepare($query);
            $sth->bindParam(':adminId', $adminId, PDO::PARAM_INT);
            $sth->execute();
            $topStars = $sth->fetchAll(PDO::FETCH_ASSOC);
            $html = '';
            foreach($topStars as $topStar){
                $html .= " <div class='score'>
                         <div style='float:left;padding:2px;' class='rank'> " .
                        $topStar['rank'] . "# </div><div style='float:left;padding:2px;font-size: 12px;'>" . $topStar["name"] . " </div><div style='float:left;padding:2px;font-size: 11px;'> ( " . $topStar["points"]. " <img src='http://mydev.com/images/star_icon.jpg' /> )</div></div><br style='clear:both;'/>";
            }
            return $html;

        }   
         catch(PDOException $err){...}
}
拒绝工作的添加:

private function getTopStars($adminId, $userId){
        try{
            $conn = DBLink::getInstance();
            $query = "SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  FROM scores p, (SELECT @rownum:=0) r, users u WHERE u.stars_enabled = 1 and (u.user_id=p.user_id and p.admin_id = :admin_id) OR (u.user_id = :uid) AND u.user_id <> :adminId ORDER BY points DESC";
            $sth = $conn->prepare($query);
            $sth->bindParam(':adminId', $adminId, PDO::PARAM_INT);
            $sth->bindParam(':uid', $userId, PDO::PARAM_INT);
            $sth->execute();
            $topStars = $sth->fetchAll(PDO::FETCH_ASSOC);
            $html = '';
            foreach($topStars as $topStar){
                $html .= " <div class='score'>
                         <div style='float:left;padding:2px;' class='rank'> " .
                        $topStar['rank'] . "# </div><div style='float:left;padding:2px;font-size: 12px;'>" . $topStar["name"] . " </div><div style='float:left;padding:2px;font-size: 11px;'> ( " . $topStar["points"]. " <img src='http://mydev.com/images/star_icon.jpg' /> )</div></div><br style='clear:both;'/>";
            }
            return $html;

        }   
         catch(PDOException $err){...}
}
如果不能以这种方式工作,我唯一能做的就是实现另一个私有方法,获取每个用户的个人信息, 使用分组和数学SQL函数在评分表中得到他的评分,我认为这是浪费服务器资源。

查询的逻辑: 我想接收目前排名最高的5个用户,使用变量或当前用户(我正在向其发送当前电子邮件)按其位置进行排序和标记,并提供相同的信息,我想从排名表中排除管理员。 你知道为什么它不起作用吗?我需要为分数列编制索引吗


提前谢谢你的帮助

这是您描述为工作的选择

SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  
FROM scores p, (SELECT @rownum:=0) r, users u 
WHERE u.stars_enabled = 1 
  AND u.user_id=p.user_id 
  AND p.admin_id = :admin_id 
  AND u.user_id <> :adminId 
ORDER BY points DESC

这是您描述为不起作用的选择

SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  
FROM scores p, (SELECT @rownum:=0) r, users u 
WHERE  u.stars_enabled = 1 
  AND (u.user_id=p.user_id AND p.admin_id = :admin_id) 
  OR  (u.user_id = :uid) 
  AND  u.user_id <> :adminId 
ORDER BY points DESC
在MySQL中,且优先级高于或,这意味着您的WHERE条件将被评估为:

(u.stars_enabled = 1 AND u.user_id=p.user_id AND p.admin_id = :admin_id)
OR  
(u.user_id = :uid AND  u.user_id <> :adminId )
这可能不是你想要的,但我不明白你想要实现什么

根据你的描述,我想得到另一个用户。。。。我很抱歉,我只能胡乱猜测你到底想做什么。第一个查询——工作查询——为您提供了与某个管理员id关联的所有用户的列表,因此它应该包括您所指的任何其他用户?没有

编辑

我想我现在明白你的问题了。你所说的其他用户已经是排名的一部分了。您试图做的是,如果某个特定用户不属于前5行,则将该用户的查询限制为5行加1行。这可以通过子查询实现:

SELECT * FROM (
    SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  
    FROM scores p, (SELECT @rownum:=0) r, users u 
    WHERE u.stars_enabled = 1 
      AND u.user_id=p.user_id 
      AND p.admin_id = :admin_id 
      AND u.user_id <> :adminId 
    ORDER BY points DESC
) WHERE rank<=5 or u.user_id=:uid

这是您描述为工作的选择

SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  
FROM scores p, (SELECT @rownum:=0) r, users u 
WHERE u.stars_enabled = 1 
  AND u.user_id=p.user_id 
  AND p.admin_id = :admin_id 
  AND u.user_id <> :adminId 
ORDER BY points DESC

这是您描述为不起作用的选择

SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  
FROM scores p, (SELECT @rownum:=0) r, users u 
WHERE  u.stars_enabled = 1 
  AND (u.user_id=p.user_id AND p.admin_id = :admin_id) 
  OR  (u.user_id = :uid) 
  AND  u.user_id <> :adminId 
ORDER BY points DESC
在MySQL中,且优先级高于或,这意味着您的WHERE条件将被评估为:

(u.stars_enabled = 1 AND u.user_id=p.user_id AND p.admin_id = :admin_id)
OR  
(u.user_id = :uid AND  u.user_id <> :adminId )
这可能不是你想要的,但我不明白你想要实现什么

根据你的描述,我想得到另一个用户。。。。我很抱歉,我只能胡乱猜测你到底想做什么。第一个查询——工作查询——为您提供了与某个管理员id关联的所有用户的列表,因此它应该包括您所指的任何其他用户?没有

编辑

我想我现在明白你的问题了。你所说的其他用户已经是排名的一部分了。您试图做的是,如果某个特定用户不属于前5行,则将该用户的查询限制为5行加1行。这可以通过子查询实现:

SELECT * FROM (
    SELECT @rownum:=@rownum+1 AS rank, u.user_id, u.contact_name AS name, p.points  
    FROM scores p, (SELECT @rownum:=0) r, users u 
    WHERE u.stars_enabled = 1 
      AND u.user_id=p.user_id 
      AND p.admin_id = :admin_id 
      AND u.user_id <> :adminId 
    ORDER BY points DESC
) WHERE rank<=5 or u.user_id=:uid

我想我可能会做一个查询,抓取前5个用户来创建一个邮件模板,然后对于所有行,不要忘记前5个,使用模板并完成用户详细信息。一个查询应该很快。第二个查询试图实现什么?我想我可能会进行一个查询,抓取前5个用户创建一个邮件模板,然后对于所有行,不要忘记前5个,使用模板并完成用户详细信息。一个查询应该很快。第二个查询的目的是什么?好的,先生,意思是我想选择不是管理员的前5个用户,还有第6个用户,实际上是电子邮件收件人,除非他是前5个用户的一部分。@OlegTikhonov根据我认为您正在尝试的内容编辑了我的答案。好的,先生,意思是,我想选择5个不是管理员的前用户,以及第6个用户,实际上是电子邮件收件人,除非他是前5个用户的一部分。@OlegTikhonov根据我认为您正在尝试的内容编辑了我的答案。