【问题标题】:PHP MYSQL query result "RANKING"PHP MYSQL 查询结果“RANKING”
【发布时间】:2011-06-01 20:35:50
【问题描述】:

我需要得到一个用户列表,按点排名,并且从我的命令行(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 可能会导致意外结果?

【问题讨论】:

    标签: php mysql ranking


    【解决方案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
    

    【讨论】:

      【解决方案2】:

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

      我不得不改变一点,因为最终结果不是我所期望的,因为我在添加增量后按点对列表进行排序。我不是 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”,这样它就不会因为在每个派生表上都没有别名而引发错误......

      【讨论】:

        【解决方案3】:

        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 将在另一个会话中执行并具有完全不同的 @排名。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-12
          • 1970-01-01
          • 1970-01-01
          • 2023-04-09
          • 1970-01-01
          • 2012-02-16
          • 2010-11-12
          • 2019-03-21
          相关资源
          最近更新 更多