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
结果当然没问题(id
、action
、fileId
、time
):
[(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 BY
fileId`:
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查询获取具有最新日期但每个唯一列限制的所有条目的主要内容,如果未能解决你的问题,请参考以下文章
当涉及到以注释开头的 SQL 查询时,Python sqlite3 模块是不是存在错误和缓慢?