PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Chạy truy vấn với LIMIT / OFFSET và cũng nhận được tổng số hàng

Có. Với một chức năng cửa sổ đơn giản:

SELECT *, count(*) OVER() AS full_count
FROM   tbl
WHERE  /* whatever */
ORDER  BY col1
OFFSET ?
LIMIT  ?

Lưu ý rằng chi phí sẽ cao hơn đáng kể so với khi không có tổng số, nhưng thường vẫn rẻ hơn so với hai truy vấn riêng biệt. Postgres thực sự phải đếm tất cả các hàng một trong hai cách sẽ áp dụng chi phí tùy thuộc vào tổng số hàng đủ điều kiện. Chi tiết:

  • Cách tốt nhất để tính kết quả trước khi LIMIT được áp dụng

Tuy nhiên , như Dani đã chỉ ra, khi OFFSET ít nhất là lớn bằng số hàng được trả về từ truy vấn cơ sở, không có hàng nào được trả lại. Vì vậy, chúng tôi cũng không nhận được full_count .

Nếu điều đó không được chấp nhận, một giải pháp khả thi để luôn trả lại tổng số đầy đủ sẽ có CTE và 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;

Bạn nhận được một hàng giá trị NULL với full_count thêm vào nếu OFFSET to quá. Mặt khác, nó được thêm vào mọi hàng như trong truy vấn đầu tiên.

Nếu một hàng có tất cả các giá trị NULL là kết quả hợp lệ có thể có, bạn phải kiểm tra offset >= full_count để phân biệt nguồn gốc của hàng trống.

Điều này vẫn thực hiện truy vấn cơ sở chỉ một lần. Nhưng nó thêm nhiều chi phí hơn cho truy vấn và chỉ trả tiền nếu điều đó ít hơn việc lặp lại truy vấn cơ sở cho số lượng.

Nếu các chỉ mục hỗ trợ thứ tự sắp xếp cuối cùng có sẵn, thì có thể trả tiền để bao gồm ORDER BY trong CTE (dư thừa).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kích hoạt kích hoạt khi cập nhật cộtA hoặc CộtB hoặc CộtC

  2. Trả lại id nếu một hàng tồn tại, INSERT nếu không

  3. PostgreSQL 'KHÔNG VÀO' và truy vấn con

  4. Quyền thu hồi PostgreSQL từ bảng pg_catalog

  5. ĐẶT HÀNG THEO danh sách giá trị IN