从SELECT中获取SQL UPDATE

时间:2014-01-25 21:24:41

标签: mysql

为什么这个查询:

UPDATE
  (SELECT A.id trophy_id
   FROM usertrophys A,
        userinfo B
   WHERE A.user_id = B.id
     AND B.cidade_new_id = 25755
     AND ban = 0
     AND A.platform = 'vita'
   ORDER BY points DESC, platinum DESC, gold DESC, silver DESC, bronze DESC, total DESC)      A
LEFT JOIN rankgeralcidade B USING (trophy_id)
SET B.rank = @r:= (@r+1)
WHERE platform = 'vita'
  AND meninas = 0
  AND cidade_id = '25755'
  AND trophy_id = B.trophy_id;</code></pre>

以此结果结束

select * from rankgeralcidade where cidade_id = 25755 and platform = 'vita' ;
+--------+-----------+----------+---------+------+-----------+-----------+---------------------+---------+---------------------+-----------+
| id     | trophy_id | platform | user_id | rank | last_rank | best_rank | best_rank_date      | meninas | date_updated        | cidade_id |
+--------+-----------+----------+---------+------+-----------+-----------+---------------------+---------+---------------------+-----------+
| 138300 |     86412 | vita     |    2774 |    1 |         1 |         1 | 2013-02-09 18:07:25 |       0 | 2012-12-25 05:20:30 |     25755 |
| 182075 |    120401 | vita     |    3546 |    2 |         0 |         0 | 2014-01-25 19:04:55 |       0 | 2014-01-25 19:04:55 |     25755 |
+--------+-----------+----------+---------+------+-----------+-----------+---------------------+---------+---------------------+-----------+
2 rows in set (0.00 sec)

当以下选择有此返回时

mysql> SELECT @r:= (@r+1), B.*
FROM
  (SELECT A.id trophy_id
   FROM usertrophys A,
        userinfo B
   WHERE A.user_id = B.id
     AND B.cidade_new_id = 25755
     AND ban = 0
     AND A.platform = 'vita'
   ORDER BY points DESC, platinum DESC, gold DESC, silver DESC, bronze DESC, total DESC) A
LEFT JOIN rankgeralcidade B USING (trophy_id);
+-------------+--------+-----------+----------+---------+------+-----------+-----------+---------------------+---------+---------------------+-----------+
| @r:= (@r+1) | id     | trophy_id | platform | user_id | rank | last_rank | best_rank | best_rank_date      | meninas | date_updated        | cidade_id |
+-------------+--------+-----------+----------+---------+------+-----------+-----------+---------------------+---------+---------------------+-----------+
|           1 | 182075 |    120401 | vita     |    3546 |    2 |         0 |         0 | 2014-01-25 19:04:55 |       0 | 2014-01-25 19:04:55 |     25755 |
|           2 | 138300 |     86412 | vita     |    2774 |    1 |         1 |         1 | 2013-02-09 18:07:25 |       0 | 2012-12-25 05:20:30 |     25755 |
+-------------+--------+-----------+----------+---------+------+-----------+-----------+---------------------+---------+---------------------+-----------+
2 rows in set (0.01 sec)

主要问题是,为什么来自rankgeralcidade的id =“182075”更新为rank = 2? 在同一个查询中,只需将UPDATE替换为SELECT,结果就好了。

1 个答案:

答案 0 :(得分:1)

以下是select查询:

SELECT @r:= (@r+1) as rank, B.*
FROM (SELECT A.id trophy_id
      FROM usertrophys A join
           userinfo B
           on A.user_id = B.id
     WHERE B.cidade_new_id = 25755 AND ban = 0 AND A.platform = 'vita'
     ORDER BY points DESC, platinum DESC, gold DESC, silver DESC, bronze DESC, total DESC
    ) A LEFT JOIN
    rankgeralcidade B
    USING (trophy_id);

外部查询没有order by子句。这意味着没有定义结果的排序。在子查询中有一个order by子句并没有什么区别。 甚至如果保留了排序(保证不是这样),join可能导致数据以不同的方式排序。

updateselect会产生不同的排序对我来说非常有意义。

如果您想要稳定的值分配,请对order byselect的最外层查询使用order by子句。

编辑:

我没有意识到MySQL不支持带有order by的{​​{1}}(因为我没有在更新上使用join)。您仍然可以使用子查询执行此操作:

order by