模拟 row_number() MySQL

Posted

技术标签:

【中文标题】模拟 row_number() MySQL【英文标题】:Simulating row_number() MySQL 【发布时间】:2014-11-14 13:21:19 【问题描述】:

你能帮我解决 mysql 中的row_number() over partition 吗?

我已经尝试了下面的脚本,但它不能正常工作。我试图只选择购买的第一个产品。我选择的列是 Client_id、product 和 purchase_date。

select * from(select * from (SELECT @rownum:=@rownum + 1 as row_number,t.* 
FROM (select cliend_id,prod,purchase_date  from Mytable    
group by cliend_id,prod,purchase_date order by cliend_id,purchase_Date) asc) t,
(SELECT @rownum := 0) r)a)b;

结果:

Row_number  Client ID   Prod    Purchase date
1               1111    apple   11-Nov-10
2               1111    yougurt 11-Nov-11
3               1111    candy   11-Nov-13
4               2222    chocolate   11-Nov-09
5               2222    pear    9-Sep-09
6               2222    beer    12-Sep-10
7               2222    cheese  12-Sep-14
8               1234    apple   15-Nov-12
9               1234    candy   4-Oct-14

我怎样才能得到这个结果?

Row_number  Client ID   Prod    Purchase date
1               1111    apple   11-Nov-10
2               1111    yougurt 11-Nov-11
3               1111    candy   11-Nov-13
1               2222    chocolate   11-Nov-09
2               2222    pear    9-Sep-09
3               2222    beer    12-Sep-10
4               2222    cheese  12-Sep-14
1               1234    apple   15-Nov-12
2               1234    candy   4-Oct-14

谢谢, 罗迪卡

【问题讨论】:

巧克力不应该从 1 开始行号吗? 【参考方案1】:

您可以“记住”上一行中cliend_id 的值,并使用该信息:

select (@rn := if(@c = cliend_id, @rn + 1,
                  if(@c := @liend_id, 1, 1)
                 )
       ) as rownum,
       cliend_id, prod, purchase_date
from (select cliend_id, prod, purchase_date 
      from Mytable    
      group by cliend_id, prod, purchase_date
     ) t cross join
     (select @rn := 0, @c := 0) vars
order by cliend_id, purchase_Date;

您应该在同一条语句中分配@rn@c,因为MySQL 不保证select 中表达式的求值顺序。

【讨论】:

谢谢戈登!我收到关于 if 语句的错误:#1064 - is not the right MySql server version to use near if(@c := @cliend_id, 1, 1))) as rownum 缺少逗号。这是一个奇怪的错误,但它可能会解决它。 我不再收到错误,但返回的 rownum 对于所有值都是 1..它不会增加

以上是关于模拟 row_number() MySQL的主要内容,如果未能解决你的问题,请参考以下文章

JPQL row_number()模拟

LINQ to SQL 模拟实现 ROW_NUMBER() OVER(ORDER BY ...) 的功能

Oracle中排序函数的用法之ROW_NUMBER()_RANK()_DENSE_RANK() OVER()的区别

row_number 和 cte 使用实例:考场监考安排

ROW_NUMBER() 替代

使用 PARTITION BY 和 ROW_NUMBER 时相同的数据,不同的结果