MySQL-从“排行榜”中获得职位

时间:2018-07-12 04:26:08

标签: mysql join sql-order-by

我正在尝试构造一个查询,在该查询中,我将获得类似于排行榜的结果,然后仅在玩家isHere = 'true'(存储在另一个表)。

here

 userID  |  isHere |
--------------------
   2    |   true
--------------------
   1    |   true
--------------------
   3    |   false
--------------------
   4    |   true

userdata

   id   |         data            |
------------------------------------
   2    |   {... "points": 5 ...}
------------------------------------
   1    |   {... "points": 10 ...}
------------------------------------
   3    |   {... "points": 2 ...}
------------------------------------
   4    |   {... "points": 28 ...}

查询:

SET
  @row_number = 0;
SELECT
  *
FROM
  (
  SELECT
    (@row_number := @row_number +1) AS num,
    userdata.id,
    userdata.data
  FROM
    userdata
  INNER JOIN
    here ON userdata.id = here.userID
  WHERE
    here.isHere = 'true'
  ORDER BY
    JSON_EXTRACT(userdata.data,
    '$.points') DESC
) AS t
WHERE
  t.id = 1

这将返回num为1 ...,因为出于某种原因,它是按用户ID / ID排序的。我通过将WHERE t.id =设置为2进行了仔细检查,而不是返回3,而是返回2 ...有人知道我的查询出了什么问题吗?

注意::我确实尝试使列data只是具有点值的BIGINT,但是发生了同样的问题。这样就消除了JSON_EXTRACT()遇到的任何问题(我想是吗?)

注释2:按照带有num列的ID单独运行内部查询,但以正确的顺序在PHPMyAdmin中显示(屏幕截图:https://gyazo.com/73177e79f4fedd4ec7e09ea0e70a9d2b

1 个答案:

答案 0 :(得分:1)

这是可行的查询:

SET
  @row_number = 0;
SELECT
  *
FROM
  (
  SELECT
    (@row_number := @row_number +1) AS num,
    userdata.id,
    userdata.data
  FROM
    userdata
  INNER JOIN
    (
    SELECT
      userdata.id,
      userdata.data
    FROM
      userdata
    INNER JOIN
      here ON userdata.id = here.userID
    WHERE
      here.isHere = 'true'
    ORDER BY
      JSON_EXTRACT(userdata.data,
      '$.points') DESC
  ) AS t ON userdata.id = t.id
) AS t2
WHERE
  id = ?

需要所有这些的唯一原因是由于MySQL执行部分查询的顺序。就像数学中按运算符使用括号一样,我在这里使用了SELECT语句。