更改查询以获得类似于MSSQL RANK函数的结果

时间:2014-08-16 14:16:27

标签: mysql

我修改了查询,如@mukhesh_soni和@salman_A所回答的Rank function in MySQL所述,以获得与MSSQL RANK()函数类似的结果,我的查询如下:

SELECT id, rank_column, 
@curRank := IF(@prevVal=rank_column, @curRank, @studentNumber) AS rank, 
@studentNumber := @studentNumber + 1 as studentNumber, 
@prevVal:=rank_column
FROM rank_table, (
SELECT @curRank :=0, @prevVal:=null, @studentNumber:=1
) r
ORDER BY rank_column 

但是查询还会在结果中返回@studentNumber和@prevVal。我怎么能省略这两个,或者我必须在PHP中忽略它们?

salman_A给出的答案类似于MSSQL DENSE_RANK(),因为我只需要在结果中省略上面两个不必要的列就需要RANK()。

1 个答案:

答案 0 :(得分:0)

天哪,dense_rank()row_number()会更容易。让我们看看我们是否可以做到这一点。摆脱prevval既简单又推荐:

SELECT id, rank_column, 
       @curRank := IF(@prevVal = rank_column,
                      @curRank,
                      if(@prevVal:=rank_column, @studentNumber, @studentNumber)
                     ) AS rank, 
       @studentNumber := @studentNumber + 1 as studentNumber
FROM rank_table CROSS JOIN
     (SELECT @curRank :=0, @prevVal:=null, @studentNumber:=1) vars
ORDER BY rank_column ;

建议使用,因为MySQL不保证select子句中表达式的评估顺序。变量赋值可以按任何顺序发生。这可以修复,但它会使更复杂的条款。我们真的只想要一个包含所有变量的表达式。你可以这样做:

SELECT id, rank_column, 
       @curRank := IF((@studentNumber := @studentNumber + 1) >= 0,
                      if(@prevVal = rank_column,
                         @curRank,
                         if(@prevVal:=rank_column, @studentNumber, @studentNumber)
                        ),
                      NULL) AS rank
FROM rank_table CROSS JOIN
     (SELECT @curRank := 0, @prevVal := null, @studentNumber := 0) vars
ORDER BY rank_column ;

注意我将初始值更改为0,因为该值在使用之前会增加。