• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

MySQL实现Oracle或者PostgreSQL的row_numberover这样的排名语法_MySQL

mysql 搞代码 4年前 (2022-01-09) 23次浏览 已收录 0个评论

gaodaima.com PostgreSQL 和Oracle 都提供了 row_number() over() 这样的语句来进行对应的字段排名, 很是方便。 MySQL却没有提供这样的语法。
Table “ytt.t1” Column | Type | Modifiers ——–+———————–+———– i_name | character varying(10) | not null rank | integer | not null

t_girl=# select * from t1 order by i_name; i_name | rank ---------+------ Charlie | 12 Charlie | 12 Charlie | 13 Charlie | 10 Charlie | 11 Lily | 6 Lily | 7 Lily | 7 Lily | 6 Lily | 5 Lily | 7 Lily | 4 Lucy | 1 Lucy | 2 Lucy | 2 Ytt | 14 Ytt | 15 Ytt | 14 Ytt | 14 Ytt | 15 (20 rows)

t_girl=# select i_name,rank, row_number() over(partition by i_name order by rank desc) as rank_number from t1; i_name | rank | rank_number ———+——+————- Charlie | 13 | 1 Charlie | 12 | 2 Charlie | 12 | 3 Charlie | 11 | 4 Charlie | 10 | 5 Lily | 7 | 1 Lily | 7 | 2 Lily | 7 | 3 Lily | 6 | 4 Lily | 6 | 5 Lily | 5 | 6 Lily | 4 | 7 Lucy | 2 | 1 Lucy | 2 | 2 Lucy | 1 | 3 Ytt | 15 | 1 Ytt | 15 | 2 Ytt | 14 | 3 Ytt | 14 | 4 Ytt | 14 | 5 (20 rows)


t_girl=# select i_name,rank, row_number() over(partition by i_name ) as rank_number from t1; i_name  | rank | rank_number ---------+------+------------- Charlie	 |   12 |           1 Charlie	|   12 |           2 Charlie	|   13 |           3 Charlie	|   10 |           4 Charlie	|   11 |           5 Lily		|    6 |           1 Lily		|    7 |           2 Lily		|    7 |           3 Lily		|    6 |           4 Lily		|    5 |           5 Lily		|    7 |           6 Lily		|    4 |           7 Lucy	|    1 |           1 Lucy	|    2 |           2 Lucy	|    2 |           3 Ytt		|   14 |           1 Ytt		|   15 |           2 Ytt		|   14 |           3 Ytt		|   14 |           4 Ytt		|   15 |           5(20 rows)

t_girl=# select i_name,rank, row_number() over() as rank_number from t1; i_name  | rank | rank_number ---------+------+------------- Lily		 |    7 |           1 Lucy	|    2 |           2 Ytt		|   14 |           3 Ytt		|   14 |           4 Charlie	|   12 |           5 Charlie	|   13 |           6 Lily		|    7 |           7 Lily		|    4 |           8 Ytt		|   14 |           9 Lily		|    6 |          10 Lucy	|    1 |          11 Lily		|    7 |          12 Ytt		|   15 |          13 Lily		|    6 |          14 Charlie	|   11 |          15 Charlie	|   12 |          16 Lucy	|    2 |          17 Charlie	|   10 |          18 Lily		|    5 |          19 Ytt		|   15 |          20(20 rows)


DELIMITER $$ USE `t_girl`$$ DROP PROCEDURE IF EXISTS `sp_rownumber`$$ CREATE PROCEDURE `sp_rownumber`( IN f_table_name VARCHAR(64), IN f_column_partitionby VARCHAR(64), IN f_column_orderby VARCHAR(64), IN f_is_asc CHAR(4) ) BEGIN — Created by ytt at 2014/1/10 — Do a row_number() over() DECLARE i INT; — Create a temporary table to save result. DROP TABLE IF EXISTS tmp_rownum; SET @stmt = CONCAT('create temporary table tmp_rownum select *,''rownum'' from ',f_table_name,' where 1 = 0'); PREPARE s1 FROM @stmt; EXECUTE s1; SET i = 0; SET @j = 0; SET @v_column_paritionby = ''; — Check whether parition column is null or not. IF (f_column_partitionby = '' OR f_column_partitionby IS NULL) THEN — No additional parition column. SET @stmt = CONCAT('insert into tmp_rownum select *,@j:= @j+1 as rownum from ', f_table_name); PREPARE s1 FROM @stmt; EXECUTE s1; ELSE — Give partition column. SET @stmt = CONCAT('select count(*) from (select count(*) from ',f_table_name,' group by ', f_column_partitionby,') as a into @cnt'); PREPARE s1 FROM @stmt; EXECUTE s1; WHILE i < @cnt DO — Get the partition value one by one. SET @stmt = CONCAT('select ',f_column_partitionby,' from ',f_table_name,' group by ',f_column_partitionby,' limit ',i,',1 into @v_column_partitionby'); PREPARE s1 FROM @stmt; EXECUTE s1; — Check whether sort is needed. IF f_column_orderby = '' OR f_column_orderby IS NULL THEN SET @stmt = CONCAT('insert into tmp_rownum select *,@j:= @j+1 as rownum from ', f_table_name,' where ',f_column_partitionby,' = ''',@v_column_partitionby,''''); ELSE SET @stmt = CONCAT('insert into tmp_rownum select *,@j:= @j+1 as rownum from ', f_table_name,' where ',f_column_partitionby,' = ''',@v_column_partitionby,''' order by ',f_column_orderby,' ',f_is_asc); END IF; SET @j = 0; PREPARE s1 FROM @stmt; EXECUTE s1; SET i = i + 1; END WHILE; END IF; — Reset all session variables. SET @j = NULL; SET @v_column_paritionby = NULL; SET @cnt = NULL; SELECT * FROM tmp_rownum; END$$ DELIMITER ;


CALL sp_rownumber('t1','i_name','rank','desc');query resulti_name	rank	rownumCharlie	13	1Charlie	12	2Charlie	12	3Charlie	11	4Charlie	10	5Lily		7	1Lily		7	2Lily		7	3Lily		6	4Lily		6	5Lily		5	6Lily		4	7Lucy	2	1Lucy	2	2Lucy	1	3Ytt		15	1Ytt		15	2Ytt		14	3Ytt		14	4Ytt		14	5

第二种,

CALL sp_rownumber('t1','i_name',NULL,NULL);query resulti_name	rank	rownumCharlie	12	1Charlie	13	2Charlie	11	3Charlie	12	4Cha<strong>本文来源gao@daima#com搞(%代@#码@网2</strong>rlie	10	5Lily		7	1Lily		7	2Lily		4	3Lily		6	4Lily		7	5Lily		6	6Lily		5	7Lucy	2	1Lucy	1	2Lucy	2	3Ytt		14	1Ytt		14	2Ytt		14	3Ytt		15	4Ytt		15	5

第三种,

CALL sp_rownumber('t1',NULL,NULL,NULL);query resulti_name	rank	rownumLily		7	1Lucy	2	2Ytt		14	3Ytt		14	4Charlie	12	5Charlie	13	6Lily		7	7Lily		4	8Ytt		14	9Lily		6	10Lucy	1	11Lily		7	12Ytt		15	13Lily		6	14Charlie	11	15Charlie	12	16Lucy	2	17Charlie	10	18Lily		5	19Ytt		15	20

gaodaima.com


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:MySQL实现Oracle或者PostgreSQL的row_numberover这样的排名语法_MySQL
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址