从sqlite获取最新更新的时间戳

从sqlite获取最新更新的时间戳,sql,sqlite,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的值最

我有一张桌子:

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的值最近一次更改时的时间戳

如何为sqlite编写sql查询,以获得以下结果:

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

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

在sql Server中,您可以从中获得最大值


选择id,maxtimstamp timestamp FROM table GROUP BY id

您需要分组两次,然后连接到主表:

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
见 编辑 在你提供了新的案例之后,我想到了这一点:

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
见 这一次,请尽全力尝试。

您可以使用窗口功能来完成此操作。它将为每个记录提供由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

你必须非常小心。假设您有如下数据:

1    test
2    news
3    test
如果希望值为1,则“按解决方案分组”将起作用。如果您想要3的值,那么问题就有点不同了。从你问题的措辞来看,你似乎想要3

SQLite的最新版本支持窗口函数。让我假设您使用的是早期版本

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

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

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;

sqlite>选择id,maxcreated_timestamp,按id从测试组创建_timestamp;将返回所有6行,这不是我想要的outcome@iveqy他可能打算使用cmd_id,而不是id。它返回两行,但不应该计算在内,因为返回组的哪一行是任意的。不幸的是,不是。从未更改的值应将其第一个创建日期作为其更新time@gordonlinoff发现此解决方案不起作用的边缘案例。请参阅对我的问题的评论。@iveqy从未更改过的值应将其第一个创建日期作为其更新时间。这些是您评论中的文字。那么问题出在哪里?没错。看,我期望结果是第2行、第5行和第9行。这真的违背了我之前说过的话吗?因为如果是的话,是我感到困惑,但我不这么认为。cmd_id的最新值应用作最新更新值。我假设问题来自于新闻->测试->新闻,它会混淆你的问题。你的结果不应该包括id为6而不是id为2的行吗?如果数据是news/news/test/news会发生什么?你想要最后一条新闻还是第一条新闻?@GordonLinoff如果你说的是一条CMD_ID,我想要最后一条。也就是说,上一次更改具有特定CMD_ID的值时。@iveqy。“我不认为福帕斯的解决方案能做到这一点。”戈登林诺夫:不?在我所有的测试中,它都成功了。你能给我一个不起作用的例子吗?我想最后一个查询在最后一行应该有num_different_after?这只给了我一个结果:46新闻123456
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;