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

Chức năng cửa sổ Postgres và nhóm theo ngoại lệ

Bạn không , trên thực tế, bằng cách sử dụng các hàm tổng hợp. Bạn đang sử dụng chức năng cửa sổ . Đó là lý do tại sao PostgreSQL yêu cầu sp.payouts.buyin được đưa vào GROUP BY mệnh đề.

Bằng cách thêm một OVER mệnh đề, hàm tổng hợp sum() được chuyển thành một hàm cửa sổ, tổng hợp các giá trị trên mỗi phân vùng trong khi giữ tất cả các hàng.

Bạn có thể kết hợp các chức năng cửa sổ và các chức năng tổng hợp . Tổng hợp được áp dụng đầu tiên. Tôi không hiểu từ mô tả của bạn về cách bạn muốn xử lý nhiều khoản thanh toán / mua lại cho mỗi sự kiện. Theo dự đoán, tôi tính tổng chúng cho mỗi sự kiện. Bây giờ Tôi có thể xóa sp.payouts.buyin từ GROUP BY mệnh đề và nhận một hàng cho mỗi playerevent :

SELECT p.name
     , e.event_id
     , e.date
     , sum(sum(sp.payout)) OVER w
     - sum(sum(s.buyin  )) OVER w AS "Profit/Loss" 
FROM   player            p
JOIN   result            r ON r.player_id     = p.player_id  
JOIN   game              g ON g.game_id       = r.game_id 
JOIN   event             e ON e.event_id      = g.event_id 
JOIN   structure         s ON s.structure_id  = g.structure_id 
JOIN   structure_payout sp ON sp.structure_id = g.structure_id
                          AND sp.position     = r.position
WHERE  p.player_id = 17 
GROUP  BY e.event_id
WINDOW w AS (ORDER BY e.date, e.event_id)
ORDER  BY e.date, e.event_id;

Trong biểu thức này:sum(sum(sp.payout)) OVER w , sum() bên ngoài là một hàm cửa sổ, sum() bên trong là một hàm tổng hợp.

Giả sử p.player_ide.event_idPRIMARY KEY trong các bảng tương ứng của chúng.

Tôi đã thêm e.event_id vào ORDER BY của WINDOW mệnh đề để đi đến một thứ tự sắp xếp xác định. (Có thể có nhiều sự kiện trong cùng một ngày.) Cũng bao gồm event_id trong kết quả để phân biệt nhiều sự kiện mỗi ngày.

Trong khi truy vấn giới hạn ở một đơn lẻ trình phát (WHERE p.player_id = 17 ), chúng ta không cần thêm p.name hoặc p.player_id đến GROUP BYORDER BY . Nếu một trong các phép nối sẽ nhân các hàng quá mức, thì tổng kết quả sẽ không chính xác (nhân một phần hoặc toàn bộ). Nhóm theo p.name sau đó không thể sửa chữa truy vấn.

Tôi cũng đã xóa e.date từ GROUP BY mệnh đề. Khóa chính e.event_id bao gồm tất cả các cột của hàng đầu vào kể từ PostgreSQL 9.1.

Nếu bạn thay đổi truy vấn để trả về nhiều người chơi cùng một lúc, hãy điều chỉnh:

...
WHERE  p.player_id < 17  -- example - multiple players
GROUP  BY p.name, p.player_id, e.date, e.event_id  -- e.date and p.name redundant
WINDOW w AS (ORDER BY p.name, p.player_id, e.date, e.event_id)
ORDER  BY p.name, p.player_id, e.date, e.event_id;

Trừ khi p.name được xác định là duy nhất (?), nhóm và thứ tự theo player_id ngoài ra để nhận được kết quả chính xác theo thứ tự sắp xếp xác định.

Tôi chỉ giữ lại e.datep.name trong GROUP BY để có thứ tự sắp xếp giống nhau trong tất cả các mệnh đề, hy vọng mang lại lợi ích về hiệu suất. Nếu không, bạn có thể xóa các cột ở đó. (Tương tự cho chỉ e.date trong truy vấn đầu tiên.)




  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ần chuyển Oracle merge thành truy vấn sang PostgreSQL

  2. Các chuỗi không có khoảng trống PostgreSQL

  3. Làm cách nào để nhận hỗ trợ LISTEN / NOTIFY không đồng bộ / hướng sự kiện trong Java bằng cách sử dụng cơ sở dữ liệu Postgres?

  4. Lỗi khi tạo cơ sở dữ liệu không gian. LỖI:không thể tải thư viện /usr/pgsql-9.1/lib/rtpostgis-2.0.so

  5. Tổng quan về Tham số kết nối sslpassword của PostgreSQL 13 libpq