选择有序选择中的前3行

时间:2011-06-02 17:50:47

标签: mysql sql-order-by limit greatest-n-per-group

我有这样的表数据:

id,time,otherdata
a,1,fsdfas
a,2,fasdfag
a,3,fasdfas
a,7,asfdsaf
b,8,fasdf
a,8,asdfasd
a,9,afsadfa
b,10,fasdf
...

基本上,我可以按照我想要的顺序选择所有数据:

select * from mytable ordered by id,time;

所以我按照我想要的顺序获得所有记录,首先按id排序,然后按时间排序。但不是获取所有记录,我需要每个id最近3次。

答案:

好吧,我想出了怎么做。我很惊讶它有多快,因为我在几百万行数据上操作,花了大约11秒钟。我在sql脚本中编写了一个程序来完成它,这就是它的样子。 - 注意,它不是获得最后3个,而是获得最后“n”个数据行。

use my_database;

drop procedure if exists getLastN;
drop table if exists lastN;

-- Create a procedure that gets the last three records for each id
delimiter //
create procedure getLastN(n int)
begin
  # Declare cursor for data iterations, and variables for storage
  declare idData varchar(32);
  declare done int default 0;
  declare curs cursor for select distinct id from my_table;
  declare continue handler for not found set done = 1;
  open curs;

  # Create a temporary table to contain our results
  create temporary table lastN like my_table;

  # Iterate through each id
  DATA_LOOP: loop

  if done then leave DATA_LOOP; end if;
  fetch curs into idData;
  insert into lastThree select * from my_table where id = idData order by time desc limit n;

  end loop;
end//

delimiter ;
call getLastN(3);
select * from lastN;

抱歉,如果这不能正常工作,我不得不更改变量名称和内容来混淆我的工作,但我运行了这段代码,得到了我需要的东西!

3 个答案:

答案 0 :(得分:4)

我认为这很简单:

SELECT * FROM `mytable`
GROUP BY `id`
ORDER BY `time` DESC
LIMIT 3

答案 1 :(得分:1)

我所知道的两种方法是(1)使用一组联合,每个联合包含一个“限制3”,或者(2)使用一个临时变量。可以找到这些方法以及其他有用的链接和讨论here

答案 2 :(得分:0)

试试这个:

select *
from mytable as m1
where (
   select count(*) from mytable as m2
   where m1.id = m2.id
) <= 3 ORDER BY id, time