从sqlite获取最新的时间戳

时间:2019-01-20 10:15:38

标签: sql sqlite

我有一张桌子:

ID | CMD_ID | VALUE | CREATED_TIMESTAMP
1       45   'test'   123456
2       46   'news'   123456
3       45   'test'   123457
4       46   'news'   123457
5       45   'TEST'   123468
6       46   'news'   123468

我想一次获取每个CMD_ID,并从最近一次获取该CMD_ID的值更改的时间戳。

如何编写一个SQL查询(用于sqlite),该查询会给我结果:

ID | CMD_ID | VALUE | CREATED_TIMESTAMP
2       46   'news'   123456
5       45   'TEST'   123468

到目前为止,我的解决方案是

select * from (select * from test as t where t.id 
in (select id from test group by value) order by id desc) group by 
cmd_id order by id;
enter code here

这给了我正确答案,但是有没有更有效的方法?

4 个答案:

答案 0 :(得分:1)

您需要分组两次,然后加入主表:

select tablename.* from tablename 
inner join 
(select cmd_id, max(minstamp) as maxstamp from
  (select cmd_id, value, min(created_timestamp) as minstamp 
  from tablename 
  group by cmd_id, value)
group by cmd_id) as t
on t.cmd_id = tablename.cmd_id and t.maxstamp = tablename.created_timestamp

请参见demo

编辑
在您提供了新案例之后,我想到了这一点:

select tablename.* from tablename inner join (
select t.cmd_id, max(t.created_timestamp) maxstamp from (
  select * from (
    select 
      t.*, (
        select value from tablename tt 
        where 
          tt.cmd_id = t.cmd_id 
          and 
          tt.created_timestamp = (
            select max(created_timestamp) from tablename 
            where 
              cmd_id = t.cmd_id 
              and
              created_timestamp < t.created_timestamp
          ) 
      ) previousvalue
    from tablename t   
  ) t  
  where 
    t.previousvalue is null 
    or 
    t.value <> t.previousvalue
  ) t
group by t.cmd_id
) t 
on t.cmd_id = tablename.cmd_id and t.maxstamp = tablename.created_timestamp

请参见demo 这次尝试一下。

答案 1 :(得分:0)

在sql服务器中,您可以从中获得最大价值

SELECT ID,来自表GROUP BY ID的最大(时间戳)时间戳

答案 2 :(得分:0)

您可以为此使用row_number窗口功能。它将为每个记录提供在“分区”(由cmd_id定义)中具有的序列号。一旦有了该数字作为额外信息,就可以过滤该数字为1的记录:

select id, cmd_id, value, created_timestamp
from   (
          select test.*,
                 row_number() over (partition by cmd_id order by created_timestamp desc) rn
          from   test
       )
where  rn = 1

答案 3 :(得分:0)

您必须非常小心。假设您有这样的数据:

1    test
2    news
3    test

如果您希望值从“ 1”开始,那么group by解决方案将起作用。如果要从“ 3”中获得该值,则问题有所不同。问题的表达方式似乎是“ 3”。

SQLite的最新版本支持窗口功能。让我假设您使用的是较早版本。

以下查询通过将0的值分配给num_different_later来标识具有相同值的最后一组行:

select t.*,
       (select count(*)
        from t t2
        where t2.cmd_id = t.cmd_id and
              t2.created_timestamp > t.created_timestamp and
              t2.value <> t.value
       ) as num_different_after
from t;

我们可以使用聚合来获取最早的时间戳:

select cmd_id, value, min(created_timestamp)
from (select t.*,
             (select count(*)
              from t t2
              where t2.cmd_id = t.cmd_id and
                    t2.created_timestamp > t.created_timestamp and
                    t2.value <> t.value
             ) as num_different_after
      from t
     ) t
where num_different_later = 0;
相关问题