我有一个包含以下架构的表:
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
我是如何实现这一目标的?
答案 0 :(得分: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只有一行,则无法获取。
只有您知道这些限制是否可以接受。
答案 1 :(得分: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;