每个ID的最后2条记录(日期)的sql查询

问题描述:

我想要做一个单一的SELECT查询,该查询返回每个ID的最新2条记录(按日期排序)。对于每个给定的ID,日期值并不总是唯一的,所以我必须处理它(查看ID = 1,我只想得到2条记录,尽管它有来自同一日期的2条记录.. 。)每个ID的最后2条记录(日期)的sql查询

例如,此表:

+------+------------+-------+ 
| ID | Date | Value | 
+------+------------+-------+ 
| 1 | 2010  | 33 | 
| 1 | 2009  | 23 | 
| 1 | 2009  | 41 | 
| 1 | 2003  | 55 | 
| 1 | 2003  | 24 | 
| 2 | 2009  | 52 | 
| 2 | 2008  | 23 | 
| 2 | 2007  | 39 | 
| 2 | 2006  | 22 | 
|  
|  
| ... | ...  | ... | 
+------+------------+-------+ 

我将有望获得:

+------+------------+-------+ 
| ID | Date | Value | 
+------+------------+-------+ 
| 1 | 2010  | 33 | 
| 1 | 2009  | 23 | 
| 2 | 2009  | 52 | 
| 2 | 2008  | 23 | 
| ... | ...  | ... | 
+------+------------+-------+ 

我使用这个脚本:

SELECT ID, Date, Value 
FROM MyTable 
WHERE Date >= IFNULL((SELECT Date 
         FROM MyTable AS T2 
         WHERE T2.ID = MyTable.ID 
         ORDER BY Date DESC 
         LIMIT 1 OFFSET 2), 
        0) 

如何显示所需的结果?

+0

感谢您的快速响应! 但我可以解决这个问题,而不使用变量? 我可以找到更简单的解决方案吗? –

您可以使用该变量,它跟踪上一条记录的id以及相同id值的分区内的记录编号。

对于工作,你首先要确保你有一个有序的结果集,然后分配这两个变量的值作为记录的顺序被处理:

select id, date, value 
from (
     select * 
     from  mytable 
     order by id, date desc 
    ) ordered, 
    (select @rn := -1, @id := -1) init 
where if(@rn := if(@id = id, @rn + 1, if(@id := id, 1, 1)), @rn, @rn) < 3; 

if结构用于评估一个表达式,然后根据第一个表达式是否被认为是false或true来评估其他东西。在这些表达式中有时会做出任务。

+0

感谢您的快速回复!但我可以在不使用变量的情况下解决这个问题吗?我可以找到更简单的解决方案吗? –

+0

不可能,因为你的表没有唯一的id列。如果可能的话,那么这将是可能的,但是查询会比这个慢几倍。 – trincot

+0

我明白了,非常感谢你的回答! –

首先,使用SELECT语句来获得ORDER所有行与count沿着每个ID,例如:

SELECT id, `date`, `value`, 
@count := IF(@previous = id, @count + 1, 1) AS `count`, @previous := id 
FROM test, (SELECT @previous := 0, @count := 1) a 
ORDER BY id ASC, `date` DESC; 

一旦这样做,你可以把它包装成另一种选择,让只数的那些行< = 2,例如:

SELECT * 
FROM (
SELECT id, `date`, `value`, 
@count := IF(@previous = id, @count + 1, 1) AS `count`, @previous := id 
FROM test, (SELECT @previous := 0, @count := 1) a 
ORDER BY id ASC, `date` DESC 
) b 
WHERE b.count <= 2; 

这里的SQL Fiddle

+0

感谢您的快速回复!但我可以在不使用变量的情况下解决这个问题吗?我可以找到更简单的解决方案吗? –

+1

一个简单的答案是否定的。你在这里试图做的是为每个组应用“限制”,这是MySQL不支持开箱即用的。 –

+0

现在很清楚,非常感谢! –