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

SQL chọn các phần tử trong đó tổng trường nhỏ hơn N

SELECT m.id, sum(m1.verbosity) AS total
FROM   messages m
JOIN   messages m1 ON m1.id <= m.id
WHERE  m.verbosity < 70    -- optional, to avoid pointless evaluation
GROUP  BY m.id
HAVING SUM(m1.verbosity) < 70
ORDER  BY total DESC
LIMIT  1;

Điều này giả định một id duy nhất, tăng dần như bạn có trong ví dụ của bạn.

Trong Postgres hiện đại - hoặc nói chung với SQL tiêu chuẩn hiện đại (nhưng không trong SQLite):

CTE đơn giản

WITH cte AS (
   SELECT *, sum(verbosity) OVER (ORDER BY id) AS total
   FROM   messages
   )
SELECT *
FROM   cte
WHERE  total <= 70
ORDER  BY id;

CTE đệ quy

Sẽ nhanh hơn đối với các bảng lớn, nơi bạn chỉ truy xuất một nhóm nhỏ.

WITH RECURSIVE cte AS (
   (  -- parentheses required
   SELECT id, verbosity, verbosity AS total
   FROM   messages
   ORDER  BY id
   LIMIT  1
   )

   UNION ALL 
   SELECT c1.id, c1.verbosity, c.total + c1.verbosity 
   FROM   cte c
   JOIN   LATERAL (
      SELECT *
      FROM   messages
      WHERE  id > c.id
      ORDER  BY id
      LIMIT  1
      ) c1 ON  c1.verbosity <= 70 - c.total
   WHERE c.total <= 70
   )
SELECT *
FROM   cte
ORDER  BY id;

Tất cả các tính năng tiêu chuẩn, ngoại trừ LIMIT .

Nói một cách chính xác, không có cái gọi là "độc lập với cơ sở dữ liệu". Có nhiều tiêu chuẩn SQL khác nhau, nhưng không có RDBMS nào tuân thủ hoàn toàn. LIMIT hoạt động cho PostgreSQL và SQLite (và một số khác). Sử dụng TOP 1 cho SQL Server, rownum cho Oracle. Đây là danh sách đầy đủ trên Wikipedia.

Tiêu chuẩn SQL:2008 sẽ là:

...
FETCH  FIRST 1 ROWS ONLY

... mà PostgreSQL hỗ trợ - nhưng hầu như không có RDBMS nào khác.

Giải pháp thay thế thuần túy hoạt động với nhiều hệ thống hơn sẽ là gói nó trong một truy vấn con và

SELECT max(total) FROM <subquery>

Nhưng nó chậm và khó sử dụng.

SQL Fiddle.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cài đặt Postgres trên windows để sử dụng với Ruby-on-Rails

  2. Khai thác tối đa chỉ mục PostgreSQL của bạn

  3. Làm thế nào để lấy bản ghi Đầu tiên và Cuối cùng từ một truy vấn sql?

  4. Có cách nào để tắt chức năng quá tải trong Postgres không

  5. Tìm các chuỗi tương tự với PostgreSQL một cách nhanh chóng