Python sqlite3 SQL查询获取具有最新日期但每个唯一列限制的所有条目

Posted

技术标签:

【中文标题】Python sqlite3 SQL查询获取具有最新日期但每个唯一列限制的所有条目【英文标题】:Python sqlite3 SQL query Get all entries with newest date but limit per single unique column 【发布时间】:2020-08-21 05:53:39 【问题描述】:

我有一个名为“fileEvents”的表。它有四列(还有更多但与问题无关):id、fileId、action 和 time。

相同的fileId、action和time值可以出现在多行中。

我想要的查询很简单,但我想不出一个可行的查询:获取每个 fileId 自特定时间以来的最新条目。

我尝试了以下方法。

首先,我将尝试从特定时间开始按时间排序所有条目:

SELECT * FROM `fileEvents` ORDER BY `time` DESC WHERE `time` < 1000

结果当然没问题(idactionfileIdtime):

[(6, 0, 3, 810), (5, 0, 3, 410), (2, 0, 1, 210), (3, 0, 2, 210), (4, 0, 3, 210), (1, 0, 1, 200)]

所以一切都已排序。但现在我只想要唯一的fileIds. So I add a GROUP BYfileId`:

SELECT * FROM `fileEvents` GROUP BY `fileId` ORDER BY `time` DESC WHERE `time` < 1000

这当然是错的。因为首先它会对结果进行分组,然后对它们进行排序,但是它们已经分组了,所以没有排序:

[(3, 0, 2, 210), (4, 0, 3, 210), (1, 0, 1, 200)]

当我尝试反转 GROUP BY 和 ORDER BY 时,我收到 OperationalError: near "GROUP": syntax error

此外,当我尝试进行子查询时,我首先获取排序列表,然后将它们分组,结果是错误的:

SELECT * FROM `fileEvents` WHERE `id` IN (
SELECT `id` FROM `fileEvents` ORDER BY `time` DESC WHERE `time` < 1000
) GROUP BY `fileId`

带有(错误的)结果:

[(1, 0, 1, 200), (3, 0, 2, 210), (4, 0, 3, 210)]

我要找的结果是:

[(6, 0, 3, 810), (2, 0, 1, 210), (3, 0, 2, 210)]

有谁知道我怎样才能得到我想要的结果?我错过了什么? 非常感谢!

【问题讨论】:

【参考方案1】:

带有ROW_NUMBER()窗口功能:

select * -- replace * with the columns that you want in the result
from (
  select *, row_number() over (partition by fileid order by time desc) rn
  from fileevents 
  where time < 1000
) t
where rn = 1

【讨论】:

【参考方案2】:

这个 top-1-per-group 问题的典型解决方案是使用相关子查询进行过滤:

select fe.* 
from fileevents fe
where fe.time = (
    select max(fe1.time) 
    from fileevents fe1 
    where fe1.fileid = fe.fileid and fe1.time < 1000
)

为了提高此查询的性能,您需要在(fileid, time) 上建立索引。

【讨论】:

非常感谢它就像一个魅力!我从未听说过相关子查询。我会调查的。 对此答案的一点说明:使用几行时很好。但是当我用超过 100k 个条目填充表时,执行时间会迅速增长。在我的情况下,forpass 的解决方案的执行速度确实快了 136 倍(!),结果相同。

以上是关于Python sqlite3 SQL查询获取具有最新日期但每个唯一列限制的所有条目的主要内容,如果未能解决你的问题,请参考以下文章

尝试在SQLite3中创建具有多个条件的SQL VIEW

SQLite3 数学函数 Python

当涉及到以注释开头的 SQL 查询时,Python sqlite3 模块是不是存在错误和缓慢?

Sqlite3数据库Python基础操作

sqlite3 fetchone() 返回 None 或其他值

python sqlite中通过字段名获取查询结果