Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用postgresql连接一对多表时如何使用限制和偏移量?_Sql_Postgresql_Sql Order By_Window Functions_Sql Limit - Fatal编程技术网

使用postgresql连接一对多表时如何使用限制和偏移量?

使用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方法可能造成的速度减慢。在上面的示例中,它工作正常,记录数始终等于限制,如果在末尾,则等于

我正在使用sqlalchemy core和postgres数据库,并正在实现

对于分页,我只使用基本限制和偏移量。例如,使用以下两个表:

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,那么在您的版本中,我只得到第三行。而不是第三,第四,第五。