在加入另一个表后对MySQL结果进行排名,并按条件

时间:2017-05-23 02:28:03

标签: mysql left-join rank leaderboard cross-join

我找到了如何对结果进行排名,但尚未找到解决方案,以便在按条件过滤后对其进行排名。我需要做的是:

1)按降序排序分数
2)使用帐户表加入结果
3)按年龄和性别(来自帐户表)过滤结果 4)对它们进行排名 5)在一系列排名中获取结果(IE:25-75,但为了简单起见,我将0-10放在下面)

我发现的每个解决方案要么没有对它们进行正确排名,要么对它们进行排名,然后对结果进行过滤。然而,当我想要1,2,3,4,5等等或25,26,27,28,29等时,这给我留下了1,3,4,6,10等等等等。

这就是我现在所拥有的:

SELECT a.id, a.username, a.country, score, user_id, duration, rank
FROM (
    SELECT s.*, a.age, a.gender, @rownum := @rownum + 1 AS rank
    FROM scores s,
        (SELECT @rownum := 0) r
    LEFT JOIN accounts a ON 1
    WHERE a.age>=18 && a.age<=35 && a.gender='m'
    ORDER BY score DESC, duration DESC, time ) `selection`
LEFT JOIN accounts a ON a.id=user_id
WHERE rank >= 0 && rank <= 10 && a.age>=18 && a.age<=35 && a.gender='m'

上述问题的问题在于它给出了正确的排名,没有任何差距,但分数完全没有问题。 IE浏览器。 IE,1,10,7,105,50等。它们按照它们在数据库中的顺序出现,未分类。

这是我之前的查询:

SELECT a.id, a.username, a.country, score, duration, rank
FROM (
    SELECT s.*, @rownum := @rownum + 1 AS rank
    FROM scores s,
        (SELECT @rownum := 0) r
    ORDER BY score DESC, duration DESC, time ) `selection`
LEFT JOIN accounts a ON a.id=user_id
WHERE rank >= 0 && rank <= 10 && a.age>=18 && a.age<=35 && a.gender='m'

此查询为我提供了正确排序的分数,但排名为3,5,8,9,13而不是1,2,3,4,5。

这是一些真实的样本数据...
为了节省时间,id,用户名,国家/地区都被省略了,因为它们是不相关的数据,只是在表格中一直重复。正如条件所示,年龄一直是'34',国家和用户名一直是相同的,因为这个特定用户是表中唯一一个年龄为34岁的用户。

上面的第一个查询具有适当的排名,但排序错误排序(IE。与添加到数据库中的顺序相同):

  age | score | rank
--------------------
  34  |   5   |  1
  34  |   1   |  2
  34  |  22   |  3
  34  |  13   |  4
  34  |  23   |  5
  34  |  23   |  6
  34  |  34   |  7
  34  |  32   |  8
  34  |  58   |  9
  34  |  76   |  10

上面的第二个查询,排序正确,但在排名时排名仍会考虑其他用户,然后在最终结果中排除:

  age | score | rank
---------------------
  34  |  76   |  3  --- This should have started at 1
  34  |  62   |  4
  34  |  58   |  5
  34  |  42   |  7  --- Notice 6 was skipped
  34  |  34   |  8
  34  |  32   |  9
  34  |  29   |  10

我的期望:

  age | score | rank
--------------------
  34  |  76   |  1
  34  |  62   |  2
  34  |  58   |  3
  34  |  42   |  4
  34  |  34   |  5
  34  |  32   |  6
  34  |  29   |  7

2 个答案:

答案 0 :(得分:0)

我可以根据您的示例数据集提供以下查询:

SET @rank = 0;
SET @score = NULL;

SELECT
    age,
    @rank:=CASE WHEN @score = score THEN @rank ELSE @rank + 1 END AS rank,
    @score:=score AS score
FROM scores
ORDER BY rank;

根据&#34; rank&#34;的定义计算得分的等级。通常使用。如果两个分数相同,则它们具有相同的等级。如果您真的想要行号,则可以轻松修改上述查询。

<强>输出:

enter image description here

在这里演示:

Rextester

答案 1 :(得分:0)

SELECT a.id, a.username, a.country, score, user_id, duration, rank
FROM (
    SELECT s.*, a.age, a.gender, @rownum := @rownum + 1 AS rank
    FROM scores s,
        (SELECT @rownum := 0) r
    LEFT JOIN accounts a ON 1
    WHERE a.age>=18 && a.age<=35 && a.gender='m'
    ORDER BY score DESC, duration DESC, time ) `selection`
LEFT JOIN accounts a ON a.id=user_id
WHERE rank >= 0 && rank <= 10 && a.age>=18