为每个用户选择最新条目而不使用 group by (postgres)
Posted
技术标签:
【中文标题】为每个用户选择最新条目而不使用 group by (postgres)【英文标题】:Select newest entry for each user without using group by (postgres) 【发布时间】:2020-11-19 04:09:48 【问题描述】:我有一张表myTable
,有四列:
id UUID,
user_id UUID ,
text VARCHAR ,
date TIMESTAMP
(id
是主键,user_id
在此表中不是唯一的)
我想检索按其最新条目排序的user_id
s,我目前正在使用此查询:
SELECT user_id FROM myTable GROUP BY user_id ORDER BY MAX(date) DESC
问题是GROUP BY
需要很长时间。有没有更快的方法来实现这一点?我尝试使用带有PARTITION BY
的窗口函数,如此处所述Retrieving the last record in each group - mysql,但它并没有真正加快速度。我还确保 user_id
已编入索引。
我的 postgres 版本是 10.4
编辑:我当前使用的上述查询在功能上是正确的,问题是它很慢。
【问题讨论】:
“按最新条目排序”是什么意思?您想仅查看最新条目(您的标题所暗示的内容)还是全部,但使用某种特殊的排序顺序? 我想要 all user_ids,按每个 user_id 的最新日期排序。上面的查询是正确的,只是速度很慢。我不是在寻找完整的条目,只有 user_ids。 那你为什么不能简单地使用select user_id from the_table order by user_id, "date" desc
?
也许我解释得不好,我想要所有的 user_id,但每个 user_id 只需要一次。
【参考方案1】:
您的查询似乎是满足您要求的相关方法:
select user_id
from mytable
group by user_id
order by max(date) desc
我建议在(user, date desc)
上建立索引以加快速度。它必须是两个列上的单个索引。
您也可以尝试distinct on
,这可能或可能不会为您提供更好的性能:
select user_id
from (
select distinct on(user_id) user_id, date
from mytable
order by user_id, date desc
) t
order by date desc
【讨论】:
索引应该在(user_id, date DESC)
@VesaKarjalainen:啊,是的,显然……谢谢。
我最终喜欢上了这个 PostgreSQL SQL 扩展。非常方便。
@GMB 现在,当然,我希望能够为每组保留不止一行。也许像distinct (5) on (user_id)
这样的东西?我知道我知道。我现在要求太多了:D
@TheImpaler: 不,distinct on
不能那样做...在这种情况下,您需要采用古老的 row_number()
方法。【参考方案2】:
从user_id, date desc
上的索引开始。这可能会有所帮助。
你也可以尝试过滤——一旦你有了这样的索引:
select t.user_id
from myTable t
where t.date = (select max(t2.date)
from myTable t2
where t2.user_id = t.user_id
)
order by t.date desc
但是,您可能会发现 order by
最终花费的时间几乎与 group by
一样多。
这个版本肯定会为子查询使用索引:
select user_id
from (select distinct on (user_id) user_id, date
from myTable t
order by user_id, date desc
) t
order by date desc;
【讨论】:
添加索引加快了速度:)。此外,您的两个建议都比我当前的查询更快,尽管第一种方法给出了一些重复,大概是因为一些 user_ids 有多个具有相同最新日期的条目。以上是关于为每个用户选择最新条目而不使用 group by (postgres)的主要内容,如果未能解决你的问题,请参考以下文章
选择描述字段而不将其包含在 GROUP BY 子句中时 GROUP BY id 的最佳方法
在 sqlalchemy 中使用 distinct()/group_by() 获取基于每个“名称”列的最新记录