我需要获得一个用户列表按点排名,并从我的命令行(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可能会导致意外的结果?
答案 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将在另一个会话中执行并具有完全不同的@秩。