【发布时间】:2021-01-17 16:17:57
【问题描述】:
我正在使用带有 postgres 数据库的 sqlalchemy 核心,并且正在实现 JSON:API spec。
对于分页,我只使用基本的LIMIT 和OFFSET。因此,例如以下两个表:
session
id
name
appearance
id
date
session_id
对于会话,我可以简单地对其进行分页:
SELECT id, name FROM session LIMIT 20 OFFSET 40
由于数据保存时间的限制,我们的数据库只能增长到如此之大,所以我不担心LIMIT OFFSET 方法可能造成的减速。在上面的示例中,它工作正常,记录数始终等于限制,或者如果在最后,则更少。但是当我有以下问题时,我的问题就来了:
SELECT s.id, s.name, a.date FROM session s JOIN appearance a on s.id = a.session_id LIMIT 3 OFFSET 0
因为可能有两个 appearance 行引用会话,所以我最终可能会得到类似的结果:
s.id s.name a.date
1 FirstSesh 24/04/14
1 FirstSesh 01/01/20
2 Hello 09/09/10
现在我只返回了一行,可能还有另一行,或者只是另一行的一部分。
我想到的第一个解决方案是:
SELECT s.id, s.name, a.date FROM (SELECT id, name FROM session LIMIT 3 OFFSET 0) s JOIN appearance a on s.id = a.session_id
但现在这会限制在 s 上使用 WHERE 或 ORDER 的能力,因为它将被限制为三个。而且我不能只将所有这些条件放在子查询中,因为我建立 JSON:API 的关系部分的方式,并且因为我想限制我是否返回 session 也基于如果例如Appearances.date 在 2012 年之前。这会导致同样的问题。
作为参考,我的 JSON:API 设置中的每种类型都有自己的查询,然后在用于关系时,这些查询用作子查询,这允许简单的递归关系和新关系的简单实现。
如果我可以根据会话 id 的组来执行类似使用 LIMIT 和 OFFSET 的操作,那么我认为这可能有效吗?但我不确定我会怎么做?
【问题讨论】:
标签: sql postgresql sql-order-by window-functions sql-limit