6

我有一个具有以下架构的表:

id, field, time
3, 'test0', 2012-08-29
3, 'test1', 2012-08-30
3, 'test2', 2012-08-31
2, 'test0', 2012-08-19
2, 'test1', 2012-08-20
2, 'test2', 2012-08-26
...

我需要为列表中的每个 id 找到它的最后一个和最后一个值。例如,如果 ids = [2,3] 结果应该返回

3, 'test1', 2012-08-30
3, 'test2', 2012-08-31 
2, 'test1', 2012-08-20
2, 'test2', 2012-08-26

如果我只需要最后一个值,我会使用

SELECT *
FROM table
WHERE id IN (2, 3)
GROUP BY id

有什么想法可以实现这一目标吗?

4

2 回答 2

3

如果每个 ID 号的时间都是唯一的,这将起作用。

SELECT d.id, d.field,d.time
  FROM d d
  JOIN (
    SELECT max(d.time)m, d.id
      FROM d
      JOIN (
         SELECT max(time) m, id
           FROM d
       GROUP BY id
      )e ON d.id=e.id AND e.m>d.time
      GROUP BY d.id
   )e ON d.time >= e.m AND d.id = e.id

这是它的工作原理。这个嵌套查询获取每个 id 的最新时间。

         SELECT max(time) m, id
           FROM d
       GROUP BY id

然后,依次嵌套到这个查询中,它为您提供每个 id 的倒数第二个时间(不包括最新时间的行子集的最新时间)。

    SELECT max(d.time)m, d.id
      FROM d
      JOIN (
         SELECT max(time) m, id
           FROM d
       GROUP BY id
      )e ON d.id=e.id AND e.m > d.time

最后,完整查询(如上图所示)获取时间大于或等于第二个最晚时间的所有行。

如果您的时间不是唯一的——也就是说,您有一些行出现相同的 ID 和时间,则每个 ID 可能会获得多于两行。但你总是会得到最近的两个时间。

如果一个特定的 ID 只有一行,你不会得到它。

只有您知道这些限制是否可以接受。

去拉小提琴! http://sqlfiddle.com/#!2/82719/5/0

于 2012-09-01T18:35:17.220 回答
1

试试这个

SELECT *
    FROM table
    WHERE id = '1'
    ORDER BY `id` desc
    LIMIT 0,2
UNION
    SELECT *
    FROM table
    WHERE id = '2'
    ORDER BY `id` desc
    LIMIT 0,2

更新:

如果也可以尝试这样的事情:

SELECT t1.*
FROM `tablename` t1
LEFT OUTER JOIN `tablename` t2
  ON (t1.id = t2.id AND t1.time > t2.time)
GROUP BY t1.id, t1.field, c1.time
HAVING COUNT(*) < 2;

参考

于 2012-09-01T18:25:36.900 回答