postgresql 是否可以在过滤和限制的查询集中获得最大ID而不获取?

hgqdbh6s  于 2023-05-17  发布在  PostgreSQL
关注(0)|答案(2)|浏览(136)

假设我在db中有一个表,其中的行如下所示:
| ID|富|
| --------------|--------------|
| 十九岁|1|
| 二十|1|
| 三十八|二|
| 四十四|1|
| 五十|二|
| 六十一|1|
我想像这样从queryset中获取max id(在本例中为50):

MyModel.objects.filter(foo=2).order_by('id').values_list('id')[:limit]

当然,limit可以大于总行数。我可以通过获取所有QuerySet,将其转换为List并使用最后一项来实现

list(MyModel.objects.filter(foo=2).order_by('id').values_list('id')[:limit])[-1]

但是我可以在数据库中这样做,而不获取整个查询集吗?
原始的sql解决方案也是受欢迎的。数据库是PostgreSQL。

更新:

我需要有限的集合内的项目最大ID,而不是所有表!例如,如果limit == 1,则将是38,如果limit == 2,则将是50,如果limit == 500,则仍将是50

hfwmuf9z

hfwmuf9z1#

您可以用途:

from django.db.models import Max

MyModel.objects.filter(foo=2).aggregate(max=Max('id'))['max']

这将进行单个查询,该查询将仅返回具有foo=2的所有MyModel的最大id
至于获取第 n 个,你可以使用一个union查询集,比如:

qs = MyModel.objects.filter(foo=2)
list(
    qs.order_by('id')[limit - 1 : limit].union(qs.order_by('-id')[:1], all=True)
)[0].id

这将检索 * 最多 * 两个记录,一个有限制,最后一个。然后,我们将它们转换为一个列表,并返回两个列表中的第一个。如果第一个有限制的查询集缺失,我们就得到最后一个(第二个查询集)。但是这些是在同一个数据库查询中检索的。

dly7yett

dly7yett2#

如果你只需要max id,这是非常基本的:

SELECT max(id) AS id
FROM   tbl
WHERE  foo = 2;

如果需要更多列或整行:

SELECT *
FROM   tbl
WHERE  foo = 2
ORDER  BY id DESC
LIMIT  1;

如果id可以是null,您可能需要:

...
ORDER  BY id DESC NULLS LAST
...

参见:

  • 按列ASC排序,但首先是NULL值?

如果表很大并且性能很重要,那么(foo, id DESC)上的multicolumn index将是理想的。(或者(foo, id DESC NULLS LAST),如果id可以是null。)只在(foo, id)上几乎一样好。如果同一个foo只有几行,那么(foo)就足够了。

相关问题