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

时间:2017-05-27 11:36:58

标签: mysql

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

例如,对于此表:

+------+------------+-------+
|  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)

如何显示所需的结果?

2 个答案:

答案 0 :(得分:2)

您可以使用变量来跟踪前一记录的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构造用于评估表达式,然后根据第一个表达式是假还是true来评估其他内容。在这些表达中,有时会进行分配。

答案 1 :(得分:1)

首先,使用SELECT语句获取ORDER中的所有行以及每个ID的count,例如:

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;

完成后,您可以将其包装到另一个select中,并仅获取count&lt; = 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