Bạn đang gặp phải aggregate fanout issue
. Điều này xảy ra bất cứ khi nào bảng chính trong một truy vấn chọn có ít hàng hơn bảng phụ mà nó được tham gia. Kết quả nối trong các hàng trùng lặp. Vì vậy, khi các hàm tổng hợp được áp dụng, chúng sẽ hoạt động trên các hàng phụ.
Ở đây, bảng chính đề cập đến bảng mà các hàm tổng hợp được áp dụng. Trong ví dụ của bạn,
* SUM(matters.fee)
>> tổng hợp trên bảng matters
.
* SUM(advicetime*advicefee)
>> tổng hợp trên bảng actions
* fixedfee='Y'
>> điều kiện trên bảng matters
Để tránh vấn đề fanout:
* Luôn áp dụng các hàm tổng hợp cho bảng chi tiết nhất trong một phép nối.
* Trừ khi hai bảng có mối quan hệ 1-1, không áp dụng các hàm tổng hợp trên các trường từ cả hai bảng.
* Nhận các tổng hợp của bạn một cách riêng biệt thông qua các truy vấn con khác nhau và sau đó kết hợp kết quả. Điều này có thể được thực hiện trong một câu lệnh SQL hoặc bạn có thể xuất dữ liệu rồi thực hiện.
Truy vấn 1:
SELECT SUM(fee) AS totfixed
FROM matters
WHERE fixedfee='Y'
Truy vấn 2:
SELECT SUM(actions.advicetime*actions.advicefee) AS totbills
FROM matters
JOIN actions ON matters.matterid = actions.matterid
WHERE matters.fixedfee = 'Y'
Query 1
&Query 2
không bị fanout. Tại thời điểm này, bạn có thể xuất cả hai và xử lý kết quả trong php. Hoặc bạn có thể kết hợp chúng trong SQL:
SELECT query_2.totbills, query_1.totfixed
FROM (SELECT SUM(fee) AS totfixed
FROM matters
WHERE fixedfee='Y') query_1,
(SELECT SUM(actions.advicetime*actions.advicefee) AS totbills
FROM matters
JOIN actions ON matters.matterid = actions.matterid
WHERE matters.fixedfee = 'Y') query_2
Cuối cùng, SUM
không sử dụng từ khóa DISTINCT
. DISTINCT
chỉ có sẵn cho COUNT
và GROUP_CONCAT
Chức năng tổng hợp. Sau đây là một đoạn SQL không hợp lệ
SUM(DISTINCT matters.fee) AS totfixed