mysql中rownumber用法_MySQL中的ROW_NUMBER()

OMG Ponies..

198

MySQL中没有排名功能.你可以得到的最接近的是使用一个变量:

SELECT t.*,

@rownum := @rownum + 1 AS rank

FROM YOUR_TABLE t,

(SELECT @rownum := 0) r

那么在我的案例中如何运作呢?我需要两个变量,col1和col2各有一个?当col1改变时,Col2需要以某种方式重置..?

是.如果是Oracle,则可以使用LEAD函数在下一个值处达到峰值.值得庆幸的是,Quassnoi涵盖了您需要在MySQL中实现的逻辑.

在同一语句中分配和读取用户定义的变量是不可靠的.这在此处记录:http://dev.mysql.com/doc/refman/5.0/en/user-variables.html:"作为一般规则,您不应该为用户变量赋值并读取其中的值你可能会得到你期望的结果,但这并不能保证.涉及用户变量的表达式的评估顺序是未定义的,可能会根据给定语句中包含的元素而改变. (9认同)

bobince..

99

我希望每个(col1,col2)对的行具有单个最高col3.

这是一个分组最大值,是最常见的SQL问题之一(因为它看起来应该很简单,但实际上并非如此).

我常常喜欢null-self-join:

SELECT t0.col3

FROM table AS t0

LEFT JOIN table AS t1 ON t0.col1=t1.col1 AND t0.col2=t1.col2 AND t1.col3>t0.col3

WHERE t1.col1 IS NULL;

"获取表格中没有其他行匹配col1的行,col2具有更高的col3."(您会注意到这一点,如果多行具有相同的col1,则大多数其他groupwise-maximum解决方案将返回多行,col2 ,col3.如果这是一个问题,你可能需要一些后期处理.)

但是,如果(col1,col2)对有col3的两个最大值,该怎么办?您最终将获得两行。 (2认同)

@Paul-要解决存在多个与每个组的最大值匹配的行而您只想抓取一行的情况,您总是可以在ON子句逻辑中添加主键来打破平局... SELECT t0.col3 FROM table AS t0左联接表AS t1上t0.col1 = t1.col1 AND t0.col2 = t1.col2 AND(t1.col3,t1.pk)>(t0.col3,t0.pk)其中t1.col1为NULL; (2认同)

Mosty Mostac..

80

我总是最终遵循这种模式.鉴于此表:

+------+------+

| i | j |

+------+------+

| 1 | 11 |

| 1 | 12 |

| 1 | 13 |

| 2 | 21 |

| 2 | 22 |

| 2 | 23 |

| 3 | 31 |

| 3 | 32 |

| 3 | 33 |

| 4 | 14 |

+------+------+

你可以得到这个结果:

+------+------+------------+

| i | j | row_number |

+------+------+------------+

| 1 | 11 | 1 |

| 1 | 12 | 2 |

| 1 | 13 | 3 |

| 2 | 21 | 1 |

| 2 | 22 | 2 |

| 2 | 23 | 3 |

| 3 | 31 | 1 |

| 3 | 32 | 2 |

| 3 | 33 | 3 |

| 4 | 14 | 1 |

+------+------+------------+

通过运行此查询,不需要定义任何变量:

SELECT a.i, a.j, count(*) as row_number FROM test a

JOIN test b ON a.i = b.i AND a.j >= b.j

GROUP BY a.i, a.j

希望有所帮助!

你是很棒的Mosty,我正是在寻找这个 (3认同)

Peter Johnso..

58

SELECT

@i:=@i+1 AS iterator,

t.*

FROM

tablename AS t,

(SELECT @i:=0) AS foo

小智..

27

查看这篇文章,它展示了如何在MySQL中使用分区模仿SQL ROW_NUMBER().我在WordPress实现中遇到了同样的情况.我需要ROW_NUMBER()并且它不在那里.

本文中的示例使用单个分区字段.要通过其他字段进行分区,您可以执行以下操作:

SELECT @row_num := IF(@prev_value=concat_ws('',t.col1,t.col2),@row_num+1,1) AS RowNumber

,t.col1

,t.col2

,t.Col3

,t.col4

,@prev_value := concat_ws('',t.col1,t.col2)

FROM table1 t,

(SELECT @row_num := 1) x,

(SELECT @prev_value := '') y

ORDER BY t.col1,t.col2,t.col3,t.col4

使用concat_ws处理null.我使用int,date和varchar对3个字段进行了测试.希望这可以帮助.查看文章,因为它打破了这个查询并解释它.

Lukasz Szozd..

22

从MySQL 8.0.0原来可以使用窗口函数.

窗口功能.

MySQL现在支持窗口函数,对于查询中的每一行,它使用与该行相关的行执行计算.这些包括RANK(),LAG()和NTILE()等函数.此外,现在可以将几个现有的聚合函数用作窗函数; 例如,SUM()和AVG().

返回其分区中当前行的编号.行数从1到分区行数.

ORDER BY影响行的编号顺序.没有ORDER BY,行编号是不确定的.

演示:

CREATE TABLE Table1(

id INT AUTO_INCREMENT PRIMARY KEY, col1 INT,col2 INT, col3 TEXT);

INSERT INTO Table1(col1, col2, col3)

VALUES (1,1,'a'),(1,1,'b'),(1,1,'c'),

(2,1,'x'),(2,1,'y'),(2,2,'z');

SELECT

col1, col2,col3,

ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS intRow

FROM Table1;

小智..

15

我还投票支持Mosty Mostacho的解决方案,对他的查询代码进行了少量修改:

SELECT a.i, a.j, (

SELECT count(*) from test b where a.j >= b.j AND a.i = b.i

) AS row_number FROM test a

哪个会得到相同的结果:

+------+------+------------+

| i | j | row_number |

+------+------+------------+

| 1 | 11 | 1 |

| 1 | 12 | 2 |

| 1 | 13 | 3 |

| 2 | 21 | 1 |

| 2 | 22 | 2 |

| 2 | 23 | 3 |

| 3 | 31 | 1 |

| 3 | 32 | 2 |

| 3 | 33 | 3 |

| 4 | 14 | 1 |

+------+------+------------+

对于表:

+------+------+

| i | j |

+------+------+

| 1 | 11 |

| 1 | 12 |

| 1 | 13 |

| 2 | 21 |

| 2 | 22 |

| 2 | 23 |

| 3 | 31 |

| 3 | 32 |

| 3 | 33 |

| 4 | 14 |

+------+------+

唯一的区别是查询不使用JOIN和GROUP BY,而是依赖于嵌套选择.

Quincy..

12

我会定义一个函数:

delimiter $$

DROP FUNCTION IF EXISTS `getFakeId`$$

CREATE FUNCTION `getFakeId`() RETURNS int(11)

DETERMINISTIC

begin

return if(@fakeId, @fakeId:=@fakeId+1, @fakeId:=1);

end$$

然后我可以这样做:

select getFakeId() as id, t.* from table t, (select @fakeId:=0) as t2;

现在您没有子视图,视图中没有子查询.

小智..

8

查询mysql中的row_number

set @row_number=0;

select (@row_number := @row_number +1) as num,id,name from sbs

Md. Kamruzza..

8

在MySQL中没有任何功能rownum,row_num()但是周围的方式如下:

select

@s:=@s+1 serial_no,

tbl.*

from my_table tbl, (select @s:=0) as s;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值