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

Tính Tổng tích lũy trong PostgreSQL

Về cơ bản, bạn cần một chức năng cửa sổ. Đó là một tính năng tiêu chuẩn ngày nay. Ngoài các chức năng cửa sổ chính hãng, bạn có thể sử dụng bất kỳ chức năng tổng hợp như chức năng cửa sổ trong Postgres bằng cách thêm một OVER mệnh đề.

Khó khăn đặc biệt ở đây là để có được các phân vùng và sắp xếp đúng thứ tự:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id
                         ORDER BY ea_year, ea_month) AS cum_amt
FROM   tbl
ORDER  BY circle_id, month;

không GROUP BY .

Tổng cho mỗi hàng được tính từ hàng đầu tiên trong phân vùng đến hàng hiện tại - hoặc trích dẫn chính xác hướng dẫn sử dụng:

Tùy chọn khung mặc định là RANGE UNBOUNDED PRECEDING , giống với RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW . Với ORDER BY , điều này đặt khung là tất cả các hàng từ phân vùng bắt đầu lên đến ORDER BY cuối cùng của hàng hiện tại ngang hàng .

... là số tiền tích lũy hoặc đang chạy mà bạn đang theo đuổi. Nhấn mạnh đậm của tôi.

Các hàng có cùng (circle_id, ea_year, ea_month) "đồng nghiệp" trong truy vấn này. Tất cả chúng hiển thị cùng một tổng đang chạy với tất cả các đồng nghiệp được thêm vào tổng. Nhưng tôi cho rằng bảng của bạn là UNIQUE trên (circle_id, ea_year, ea_month) , thì thứ tự sắp xếp là xác định và không có hàng nào có hàng ngang hàng.

Postgres 11 đã thêm các công cụ để bao gồm / loại trừ các công cụ ngang hàng với frame_exclusion mới tùy chọn. Xem:

  • Tổng hợp tất cả các giá trị không cùng nhóm

Bây giờ, ORDER BY ... ea_month sẽ không hoạt động với các chuỗi cho tên tháng . Postgres sẽ sắp xếp theo thứ tự bảng chữ cái theo cài đặt ngôn ngữ.

Nếu bạn có date thực tế các giá trị được lưu trữ trong bảng của bạn, bạn có thể sắp xếp đúng cách. Nếu không, tôi khuyên bạn nên thay thế ea_yearea_month với một cột duy nhất mon thuộc loại date trong bảng của bạn.

  • Chuyển đổi những gì bạn có với to_date() :

      to_date(ea_year || ea_month , 'YYYYMonth') AS mon
    
  • Để hiển thị, bạn có thể lấy các chuỗi gốc bằng to_char() :

      to_char(mon, 'Month') AS ea_month
      to_char(mon, 'YYYY') AS ea_year
    

Trong khi mắc kẹt với thiết kế đáng tiếc, điều này sẽ hoạt động:

SELECT ea_month, id, amount, ea_year, circle_id
     , sum(amount) OVER (PARTITION BY circle_id ORDER BY mon) AS cum_amt
FROM   (SELECT *, to_date(ea_year || ea_month, 'YYYYMonth') AS mon FROM tbl)
ORDER  BY circle_id, mon;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hàm xóa dấu trong postgreSQL

  2. Làm thế nào để cài đặt im lặng Postgresql trong Ubuntu qua. Dockerfile?

  3. Làm cách nào để buộc Postgres sử dụng một chỉ mục cụ thể?

  4. Cách so sánh hai mảng và chỉ chọn các phần tử không phù hợp Trong postgres

  5. Lập chỉ mục ando:Chỉ mục GIN