Yes.,具有简单的窗口功能:
SELECT *, count(*) OVER() AS full_count
FROM tbl
WHERE /* whatever */
ORDER BY col1
OFFSET ?
LIMIT ?
请注意,成本将大大高于没有总数的情况,但通常仍比两个单独的查询便宜.无论哪种方式,Postgres实际上都必须达到count all rows,这就需要根据符合条件的行的总数来确定成本.细节:
However、as Dani pointed out,当OFFSET
至少等于从基本查询返回的行数时,不会返回任何行.所以我们也没有得到full_count
.
如果这是不可接受的,workaround to always return the full count可能会配备CTE和OUTER JOIN
:
WITH cte AS (
SELECT *
FROM tbl
WHERE /* whatever */
)
SELECT *
FROM (
TABLE cte
ORDER BY col1
LIMIT ?
OFFSET ?
) sub
RIGHT JOIN (SELECT count(*) FROM cte) c(full_count) ON true;
如果OFFSET
太大,将得到一行带有full_count
的空值.否则,它会像第一个查询一样附加到每一行.
如果一个包含所有空值的行是一个可能的有效结果,则必须选中offset >= full_count
以消除空行来源的歧义.
这仍然只执行一次基本查询.但它会给查询增加更多开销,并且只有在这比重复基本查询的次数少的情况下,才会支付费用.
如果支持最终排序顺序的索引可用,那么将ORDER BY
包含在CTE中(冗余)可能是值得的.