ใช่. ด้วยฟังก์ชันหน้าต่างที่เรียบง่าย:
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
ต่อท้ายหากOFFSET
มีขนาดใหญ่เกินไป มิฉะนั้นจะต่อท้ายทุกแถวเหมือนในแบบสอบถามแรก
หากแถวที่มีค่า NULL ทั้งหมดเป็นผลลัพธ์ที่เป็นไปได้คุณต้องตรวจสอบoffset >= full_count
เพื่อแยกแยะจุดเริ่มต้นของแถวว่าง
การดำเนินการนี้ยังคงเรียกใช้การสืบค้นพื้นฐานเพียงครั้งเดียว แต่จะเพิ่มค่าใช้จ่ายให้กับแบบสอบถามมากขึ้นและจะจ่ายเฉพาะในกรณีที่น้อยกว่าการทำแบบสอบถามพื้นฐานซ้ำสำหรับการนับ
หากดัชนีที่สนับสนุนลำดับการจัดเรียงสุดท้ายพร้อมใช้งานอาจต้องจ่ายเพื่อรวมORDER BY
CTE ไว้ใน CTE (ซ้ำซ้อน)