Mysql排名功能的实现

Mysql不像Oracle那样有方便的排名函数可以直接使用,要实现排名功能要稍微费点周折。
1、建表及数据初始化
drop table if exists t_rank;
CREATE TABLE t_rank 
( 
pid INT(4) PRIMARY KEY AUTO_INCREMENT, 
NAME VARCHAR(20) NOT NULL, 
age INT(3), 
groupid INT 
);

INSERT INTO t_rank(NAME,age,groupid) 
VALUES 
('Peter', 19, 1), 
('Andre',20, 1), 
('Vino',20, 3), 
('John',25, 3), 
('Tom',24, 4), 
('Brian',21, 4), 
('Andy',22, 3), 
('George',23, 4), 
('Dew',23, 4), 
('Kris',25, 4), 
('Samual',25, 4), 
('William',26, 2);

2、查询:相同数值自动排名(没有并列)
-- 相同数值自动排名(没有并列)
SELECT pid, NAME, age, @curRank := @curRank + 1 AS rank 
FROM t_rank r,(SELECT @curRank := 0) t 
ORDER BY age

3、查询:相同数值相同排名(无空名次)
-- 相同数值相同排名(无空名次)
SELECT pid, NAME, age, 
CASE 
WHEN @preRank = age THEN @curRank 
WHEN @preRank := age THEN @curRank := @curRank + 1 
END AS rank 
FROM t_rank r, (SELECT @curRank := 0, @preRank := NULL ) t 
ORDER BY age

4、查询:相同数值相同排名(有空名次)
-- 相同数值相同排名(有空名次)
SELECT pid, NAME, age, 
@rownum := @rownum + 1 AS tmp, 
@incrnum := CASE 
WHEN @rowtotal = age THEN @incrnum 
WHEN @rowtotal := age THEN @rownum 
END AS rownum 
FROM 
( 
SELECT pid, NAME, age 
FROM t_rank 
ORDER BY age DESC 
) AS a,(SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0) b

-- 不展示中间过程
select pid,name,age,rownum from (
SELECT pid, NAME, age, 
@rownum := @rownum + 1 AS tmp, 
@incrnum := CASE 
WHEN @rowtotal = age THEN @incrnum 
WHEN @rowtotal := age THEN @rownum 
END AS rownum 
FROM 
( 
SELECT pid, NAME, age 
FROM t_rank 
ORDER BY age DESC 
) AS a,(SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0) b) x

5、生产使用一例
SELECT B.data_week,
      (SELECT COUNT(1) + 1
      FROM (select distinct data_week from bi_user_remain_pay_byweek ) A
      WHERE concat(substr(A.data_week,1,4),lpad(substr(A.data_week,6),2,0)) < concat(substr(B.data_week,1,4),lpad(substr(B.data_week,6),2,0))) PM
   FROM (select distinct data_week from bi_user_remain_pay_byweek ) B
ORDER BY PM;


你可能感兴趣的:(Mysql,Sql)