是。具有简单的窗口功能:
SELECT *, count(*) OVER() AS full_count
FROM tbl
WHERE
ORDER BY col1
OFFSET ?
LIMIT ?
请注意,成本将比没有总数大得多,但通常仍比两个单独的查询便宜。Postgres必须实际上以任何一种方式对所有行进行计数,这取决于符合条件的行的总数会产生费用。细节:
但是,正如Dani所指出的那样,当OFFSET
至少等于从基本查询返回的行数时,将不返回任何行。所以我们也没有得到full_count
。
如果不可接受,则始终返回全部计数的可能解决方法是CTE和OUTER JOIN
:
WITH cte AS (
SELECT *
FROM tbl
WHERE
)
SELECT *
FROM (
TABLE cte
ORDER BY col1
LIMIT ?
OFFSET ?
) sub
RIGHT JOIN (SELECT count(*) FROM cte) c(full_count) ON true;
您将获得一行NULL值,并在full_count
后面加上ifOFFSET
太大,。否则,它会像第一个查询一样附加到每一行。
如果具有所有NULL值的行是可能的有效结果,则必须检查 offset >= full_count
以消除空行的来源的歧义。
这仍然只执行一次基本查询。但这会增加查询的开销,并且仅在少于重复基本查询的次数时才支付费用。
如果支持最终排序顺序的索引可用,则可能需要将其包括ORDER BY
在CTE中(冗余)。