PHP MYSQL查询结果“RANKING”

时间:2010-12-31 03:25:43

标签: php mysql ranking

我需要获得一个用户列表按点排名,并从我的命令行(MySQL)能够生成必要的代码:

SET @rank=0;
SELECT rank, iduser, pontos FROM (
SELECT @rank:=@rank+1 AS rank,
       SUM(points.points) AS pontos,
       points.iduser,
       users.name,
       users.idade
  FROM points
       INNER JOIN
       users
       ON (points.iduser = users.id)
 WHERE (users.idade >= %s) AND (users.idade <= %s)
GROUP BY points.iduser ORDER BY pontos DESC) AS totals WHERE iduser = %s

问题是我需要在AMFPHP上运行它并且我在测试PHP文件中测试它并且似乎我不能在相同的“mysql_query”中使用SET和SELECT。

我看了,有些人习惯使用mysql_query来做这件事(我已经测试了它并且有效),但是我能相信这是有效且没有错误的吗?它是否像在MySQL事务中一样工作,或者在单独的查询中设置@rank可能会导致意外的结果?

3 个答案:

答案 0 :(得分:1)

使用此查询而不使用SET:

SELECT rank, iduser, pontos FROM (
SELECT @rank:=@rank+1 AS rank,
       SUM(points.points) AS pontos,
       points.iduser,
       users.name,
       users.idade
  FROM points
       INNER JOIN
       users
       ON (points.iduser = users.id)
             INNER JOIN
             (SELECT @rank :=0)
 WHERE (users.idade >= %s) AND (users.idade <= %s)
GROUP BY points.iduser ORDER BY pontos DESC) AS totals WHERE iduser = %s

答案 1 :(得分:1)

感谢您的快速解答。我选择尝试第一个选项并使用内部联接构建查询,并在select中设置@rank。

我不得不改变一个litle,因为最终结果不是我所期望的,因为我在添加增量后按点排序列表。我不是MySQL的专家,但这就是我现在所做的工作:

SELECT rank, pontos FROM (
SELECT @rank:=@rank+1 AS rank, iduser, idade, pontos FROM (
 SELECT SUM(points.points) AS pontos,
 points.iduser,
        users.name,
        users.idade
        FROM points 
        INNER JOIN
        users
        ON (points.iduser = users.id)
 WHERE (users.idade >= 10) AND (users.idade <= 24)
 GROUP BY points.iduser ORDER BY pontos DESC ) AS pointsList
 INNER JOIN
 (SELECT @rank :=0) AS ranker ) AS ranking WHERE iduser = 2

我不得不添加“AS”,这样就不会因为每个派生表都没有别名而抛出错误....

答案 2 :(得分:0)

PHP中的MySQL不允许在单个mysql_query()调用调用中执行多个查询,作为针对SQL注入攻击的安全措施。这可以阻止Little Bobby Tables攻击死亡(但不能防止其他类型的注入攻击)。

只要您使用与查询相同的脚本会话和相同的数据库句柄执行SET查询,就没有理由将其拆分为两个单独的调用。

mysql_query("SET @rank:=0;");
$res = mysql_query("SELECT ....");

会正常工作。但是,如果您通过AMF执行此操作并具有单独的AMF服务功能来单独执行SET和SELECT,那么大多数人都无法工作。每个AMF服务调用都是一个单独的HTTP请求,这意味着每次都有一个新的(和不同的)MySQL句柄,因此初始SET将在一个会话中完成,忘记,然后SELECT将在另一个会话中执行并具有完全不同的@秩。