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.payout
và s.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.payout
và s.buyin
từ GROUP BY
mệnh đề và nhận một hàng cho mỗi player
và event
:
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_id
và e.event_id
là PRIMARY 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 BY
và ORDER 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.date
và p.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.)