根据时间戳列选择不同的最新两行

时间:2019-01-12 13:57:21

标签: mysql sql

我有一个如下表。我想提取具有相同ID的最新(基于时间)2行。如果没有相同的行,则不返回任何内容。然后,将最新行的值减去第二个最新行的值,然后返回包含ID和值结果的表。

下面是表格。第一列是ID。第二是价值,第三是时间。 ID不是主要ID也不是唯一

Id value  time
3   2   2019-01-11 18:59:07.403
2   7   2019-01-10 18:58:40.400
4   5   2019-01-12 18:58:42.400
2   2   2019-01-11 18:59:23.147
5   -5  2019-01-12 18:58:42.400
3   8   2019-01-12 18:59:27.670
2   5   2019-01-12 18:59:43.777

结果应该是

id  value
2   3
3   6

2 个答案:

答案 0 :(得分:0)

一种可能的解决方案是使用聚合来获取多次出现的ID,并将子查询与ORDER BYLIMIT相关联以获取最新值和第二最新值。

SELECT x.id,
       (SELECT t.value
               FROM elbat t
               WHERE t.id = x.id
               ORDER BY t.time DESC
               LIMIT 0, 1)
       -
       (SELECT t.value
               FROM elbat t
               WHERE t.id = x.id
               ORDER BY t.time DESC
               LIMIT 1, 1) value
       FROM (SELECT t.id
                    FROM elbat t
                    GROUP BY t.id
                    HAVING count(*) > 1) x;

db<>fiddle

答案 1 :(得分:0)

在MySQL 8+中,您可以使用窗口函数和条件聚合

select t.id,
       sum(case when seqnum = 1 then value else - value end) as diff
from (select t.*,
             row_number() over (partition by id order by time desc) as seqnum             
      from elbat t
     ) t
where seqnum in (1, 2)
group by id
order by max(time) desc
limit 2;

可以使用变量将相同的想法应用于早期版本:

select t.id,
       sum(case when seqnum = 1 then value else - value end) as diff
from (select t.*,
             (@rn := if(@i = id, @rn + 1,
                        if(@i := id, 1, 1)
                       )
             )  as seqnum             
      from (select t.* from elbat t order by id, time desc) t cross join
           (select @i := -1, @rn := 0) params
     ) t
where seqnum in (1, 2)
group by id
order by max(time) desc
limit 2;