2014-10-27 128 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