从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;