【问题标题】:SQLITE: get last component update for each distinct componentSQLITE:获取每个不同组件的最后一个组件更新
【发布时间】:2021-02-22 12:39:44
【问题描述】:

我有一个看起来有点像这样的简单 SQLITE 数据库

ID      TID      LASTUPDATE     UPDATE
============================================
1       213      2020-09-09         ok
2       416      2019-12-25         ok
3       213      2020-11-10         meh
...
999999  899      2020-12-11         bad

每个 TID 有大约一千个 DISTINCT TID 和数十万个更新。

我想获得每个不同 TID 的最后一次更新,无论它是什么时候制作的,我想一次性完成。我不想获取所有不同的 TID,然后为每个 TID 获取其 UPDATE 和 LASTUPDATE

诸如“SELECT * FROM updates GROUP BY TID”之类的东西不起作用,因为 GROUP BY 会给出它找到的第一个 TID,而我想要它找到的最后一个,所以我不想要这个:

1       213      2020-09-09         ok
2       416      2019-12-25         ok
...

当我想要的时候(实际上,排序并不重要)

3       213      2020-11-10         meh
2       416      2019-12-25         ok
...

不幸的是,我对 SQL 的了解以简单的 CRUD 内容结束。

任何帮助表示赞赏。

(第二天)

作为对此的更新 - 无论如何对我来说 - 当表中的行数超过 200,000 时,获取所有不同 tid 然后 foreach tid 获取其最后一次更新的基本方法更快(.5s)运行时间猛增到许多秒,第 3 种方式变得更加有用,因为虽然运行需要 2.5 秒,但它似乎是一个恒定的运行时间,似乎没有太大变化。

我也无法让第二个版本工作,但有一些编辑

select t.*
from updates t join
     (select id, tid, max(t.lastupdate) as max_lastupdate from updates t group by vid) tt
      on t.id = tt.id and (t.lastupdate = tt.max_lastupdate);

我发现它的运行时间总是在 250 毫秒左右,这很容易超过两个版本。

非常感谢 Gordon Linoff,感谢您抽出宝贵的时间。

【问题讨论】:

    标签: sql sqlite window-functions partitioning


    【解决方案1】:

    一种方法使用相关子查询:

    select t.*
    from t
    where t.lastupdate = (select max(t2.lastupdate) from t t2 where t2.tid = t.tid);
    

    为了提高性能,您需要在(tid, lastupdate) 上建立索引。

    您也可以尝试将其表述为:

    select t.*
    from t join
         (select tid, max(t2.lastupdate) as max_lastupdate
          from t
          group by tid
         ) tt
         on t.id = tt.id and t.lastupdate = tt.max_lastupdate;
    

    或者:

    select t.*
    from (select t.*, 
                 row_number() over (partition by tid order by lastupdate desc) as seqnum
          from t
         ) t
    where seqnum = 1;
    

    【讨论】:

    • 不确定这是否有效,查询已经运行了 40 分钟!可能需要添加更多索引!!!
    • 好的,但即使进行了优化,仍然需要 5 分钟以上才能恢复结果,这对于我的需要 - GUI 显示更新 - 不起作用。如果我这样做很长,请获取不同 tid 的列表,然后获取仍然很慢(0.5 秒)但足够好的最大 lastupdate foreach tid - 谢谢你教会了我一些东西。
    • @push22 。 . .我添加了另外两个选项。我建议使用相关子查询,因为我认为它会最快。如果你想试试其他的,我会对他们的表现感兴趣。
    • 感谢最后一位将运行时间缩短至 2.5 秒!更快,但它仍然更快 - 但是,嘿,它就是这样!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多