2014-10-27 127 views
1

我正在计算mysql中一些数据的spearmans排名相关性。为此,我需要按降序排列我的数据。我得到了这个工作,但是当2行具有相同的变量时,等级应该是2个或更多等级的平均值。 此处作为一例是与当前行列一些示例数据和预期的行列在mysql中获取多个排名的平均数

| id|var|rank| 
| 8 | 1 | 1 | 
| 2 | 2 | 2 | # rank should be 2.5 
| 6 | 2 | 3 | # rank should be 2.5 
| 4 | 3 | 4 | 
| 5 | 4 | 5 | 
| 1 | 5 | 6 | 
| 3 | 6 | 7 | # rank should be 8 
| 7 | 6 | 8 | # rank should be 8 
| 9 | 6 | 9 | # rank should be 8 

我的查询看起来是这样的现在:

SET @rownum := 0; 
SET @rownum2 := 0; 
SELECT rank_x.id, rank_x.var1, rank_x.rk_x 
FROM 
    (SELECT id, @rownum := @rownum + 1 AS rk_x, var1 
    FROM sampledata order by var1 asc) as rank_x; 

回答

0

可以通过设定的序号做到这一点,然后取平均值。这需要一些嵌套子查询,但是可行。我们的想法是:

  • 首先分配顺序值
  • 然后找到最多每个ID。
  • 然后找到分钟
  • 然后取平均值

查询看起来像:

SELECT id, var1, (minrn + maxrn)/2 
FROM (SELECT sd.*, 
      (@maxrn := if(@v2 = var1, @maxrn, 
          if(@v2 := var1, rn, rn) 
         ) 
      ) as maxrn 
     FROM (SELECT sd.*, 
        (@minrn := if(@v = var1, @minrn, 
            if(@v := var1, rn, rn) 
           ) 
        ) as minrn 
      FROM (SELECT id, var1, (@rn := @rn + 1) as rn 
        FROM sampledata sd CROSS JOIN 
         (SELECT @rn := 0) vars 
        ORDER BY var1 asc 
       ) sd CROSS JOIN 
       (SELECT @minrn := 0, @v := -1) vars 
      ORDER BY var1, rn 
      ) sd CROSS JOIN 
      (SELECT @maxrn := 0, @v2 := -1) vars 
     ORDER BY var1, rn desc 
    ) sd; 
+0

非常感谢,它的伟大工程!你所犯的唯一错误(我猜)是第四行的“@rn”。我认为它应该是“rn”。 无论如何,完美的解决方案! – Myrdox 2014-10-27 12:11:49

+0

@Myrdox。 。 。固定。 – 2014-10-27 12:18:17