使用postgresql连接一对多表时如何使用限制和偏移量?
我正在使用sqlalchemy core和postgres数据库,并正在实现 对于分页,我只使用基本限制和偏移量。例如,使用以下两个表:使用postgresql连接一对多表时如何使用限制和偏移量?,sql,postgresql,sql-order-by,window-functions,sql-limit,Sql,Postgresql,Sql Order By,Window Functions,Sql Limit,我正在使用sqlalchemy core和postgres数据库,并正在实现 对于分页,我只使用基本限制和偏移量。例如,使用以下两个表: session id name appearance id date session_id 对于会话,我可以简单地分页,如下所示: 从会话限制20偏移量40中选择id、名称 由于数据可以保存的时间有限,我们的数据库只能增长如此之大,因此我不担心LIMIT OFFSET方法可能造成的速度减慢。在上面的示例中,它工作正常,记录数始终等于限制,如果在末尾,则等于
session
id
name
appearance
id
date
session_id
对于会话,我可以简单地分页,如下所示:
从会话限制20偏移量40中选择id、名称
由于数据可以保存的时间有限,我们的数据库只能增长如此之大,因此我不担心LIMIT OFFSET方法可能造成的速度减慢。在上面的示例中,它工作正常,记录数始终等于限制,如果在末尾,则等于或小于限制。但我的问题是:
选择s.id、s.name、a.date FROM session s JOIN外观a on s.id=a.session\u id LIMIT 3偏移量0
因为可能有两个外观行引用会话,所以我可能会得到如下结果:
s.id s.name a.date
1 FirstSesh 24/04/14
1 FirstSesh 01/01/20
2 Hello 09/09/10
现在我只返回了一行,可能是另一行,或者只是另一行的一部分
我想到的第一个解决方案是:
选择s.id、s.name、a.date FROM SELECT id、name FROM session LIMIT 3 OFFSET 0 s连接外观a on s.id=a.session\u id
但现在,由于在s上使用WHERE或ORDER的能力受到限制,因为它将被限制为三个。我不能把所有这些条件都放在子查询中,因为我已经建立了JSON:API的关系部分,因为我想限制我是否返回会话,也要基于Examples.date是否在2012之前。这会引起同样的问题
为了便于参考,我的JSON:API设置中的每种类型都有自己的查询,然后当在关系中使用这些查询时,它们被用作子查询,这允许简单的递归关系和新关系的简单实现
如果我可以做一些类似于基于会话id的组使用限制和偏移的事情,那么我认为这可能有效吗?但我不知道该怎么做?您可以使用窗口功能。例如,这将为您提供按id排序的前3个会话,以及所有相应的外观,无论它们中有多少匹配
SELECT s.id, s.name, a.date
FROM (SELECT s.*, ROW_NUMBER() OVER(ORDER BY id) rn FROM sessions) s
INNER JOIN appearance a ON s.id = a.session_id
WHERE s.rn BETWEEN 0 AND 3
ORDER BY s.rn, a.date
然后,可以通过更改BETWEEN条件的边界对结果集进行分页
编辑
或者:
SELECT id, name, date
FROM (
SELECT s.id, s.name, a.date,
DENSE_RANK () OVER(ORDER BY id) rn
FROM sessions s
INNER JOIN appearance a ON s.id = a.session_id
WHERE a.is_admin = 1
) c
WHERE s.rn BETWEEN 0 AND 3
ORDER BY rn, date
您可以使用窗口函数。例如,这将为您提供按id排序的前3个会话,以及所有相应的外观,无论它们中有多少匹配
SELECT s.id, s.name, a.date
FROM (SELECT s.*, ROW_NUMBER() OVER(ORDER BY id) rn FROM sessions) s
INNER JOIN appearance a ON s.id = a.session_id
WHERE s.rn BETWEEN 0 AND 3
ORDER BY s.rn, a.date
然后,可以通过更改BETWEEN条件的边界对结果集进行分页
编辑
或者:
SELECT id, name, date
FROM (
SELECT s.id, s.name, a.date,
DENSE_RANK () OVER(ORDER BY id) rn
FROM sessions s
INNER JOIN appearance a ON s.id = a.session_id
WHERE a.is_admin = 1
) c
WHERE s.rn BETWEEN 0 AND 3
ORDER BY rn, date
这也有同样的问题吗?例如,让我们想象一下外观有另一个字段,is_admin。如果我添加到查询中,其中is_admin为True,那么它只适用于已经选择的三个会话。因此,如果前三个会话的外观不是is_admin为True,或者第三、第四、第五和第六个会话的外观是is_admin,那么在您的版本中,我只得到第三行。而不是得到第三、第四和第五。这有同样的问题吗?例如,让我们想象一下外观有另一个字段,is_admin。如果我添加到查询中,其中is_admin为True,那么它只适用于已经选择的三个会话。因此,如果前三个会话的外观不是is_admin为True,或者第三、第四、第五和第六个会话的外观是is_admin,那么在您的版本中,我只得到第三行。而不是第三,第四,第五。