INNER JOIN在第二个表中的位置

时间:2013-04-17 09:11:39

标签: sql inner-join

我正在为游戏运行CodeIgniter后端,其中用户信息和高分表保存在数据库中。每个用户只能以个人最佳状态输入高分,因此每个用户只有一个条目

现在我需要为客户导出该数据,以便他可以选择随机获胜者。 基本上我想给他所有的用户数据加上用户点和他在高分榜中的位置。

我在弄清楚如何获得高分榜中的位置时遇到了问题。

假设我的用户表看起来像这样

user_table
| id|name|
|...| ...|

highscore_table
|id |user_id|points|
|...|  ...  |  ... |

SQL语句(不包括高分位置)看起来像这样

SELECT user_table.id, name, points
FROM user_table
INNER JOIN highscore_table ON user_table.id = highscore_table.user_id
ORDER BY name

导出的数据应该如下所示

|id | name|points|hs_position|
|...| ... |  ... |    ...    |

通常当我请求高分时,我会做类似的事情,但按points对数据进行排序。这不是一个选择。

有人可以告诉我如何实现这一目标,引导我走向正确的方向,或者只是简单明了地告诉我这是不可能的吗?

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

  

我在弄清楚如何获得这个位置时遇到了问题   高分榜。

如果您使用的是SQL-Server,则可以使用DENSE_RANK作为HS-Rank,使用ROW_NUMBER获取每位用户最高点的行:

WITH cte 
     AS (SELECT user_table.id, 
                name, 
                points, 
                hs_position=Dense_rank() 
                              OVER( 
                                ORDER BY points DESC), 
                Personalbest_Num=Row_number() 
                                   OVER( 
                                     partition BY id 
                                     ORDER BY points DESC) 
         FROM   user_table 
                INNER JOIN highscore_table 
                        ON user_table.id = highscore_table.user_id) 
SELECT id, 
       name, 
       points, 
       hs_position 
FROM   cte 
WHERE  personalbest_num = 1 
ORDER  BY hs_position ASC, 
          name ASC

答案 1 :(得分:1)

如果您使用的是不支持排名功能的RDBMS(例如SQLite),那么实现此目的的一种方法是通过子查询 - 如下所示:

SELECT u.id, u.name, h.points, 
       (select count(*) + 1
        from highscore_table h2 
        WHERE h2.points > h.points) hs_position
FROM user_table u
INNER JOIN highscore_table h ON u.id = h.user_id
ORDER BY u.name

SQLFiddle here

(如果您想获得密集排名的高分,请将count(*) + 1更改为count(distinct h2.points) + 1。)

答案 2 :(得分:0)

这是MySQL的解决方案:

SELECT user_table.id, name, points, hs_table.rank
FROM user_table
INNER JOIN 
(
  SELECT hs.*, IF(@prev != points, @pos:=@pos + 1, @pos) as rank
  , @prev:=points
  FROM highscore_table hs,
       (SELECT @pos:=0, @prev:=NULL) vars
  ORDER BY points DESC
) hs_table
 ON user_table.id = hs_table.user_id
ORDER BY name

积分相同的人将具有相同的等级。

相关问题