Khi bạn sử dụng GROUP BY, bạn chỉ có thể sử dụng các biểu thức trong danh sách lựa chọn nếu chúng có một giá trị duy nhất cho mỗi nhóm. Nếu không, bạn sẽ nhận được kết quả truy vấn không rõ ràng.
Trong trường hợp của bạn, MySQL tin rằng s.status
có thể có nhiều giá trị cho mỗi nhóm. Ví dụ:bạn đang nhóm theo p.products_id
nhưng s.status
là một cột trong bảng khác specials
, có lẽ trong mối quan hệ một-nhiều với bảng products
. Vì vậy, có thể có nhiều hàng trong specials
với cùng một products_id
, nhưng các giá trị khác nhau cho status
. Nếu đúng như vậy, giá trị nào cho status
nên sử dụng truy vấn? Nó không rõ ràng.
Trong dữ liệu của mình, bạn có thể tình cờ giới hạn các hàng sao cho bạn chỉ có một hàng trong specials
cho mỗi hàng trong products
. Nhưng MySQL không thể đưa ra giả định đó.
MySQL 5.6 trở về trước cho phép bạn viết các truy vấn không rõ ràng như vậy, tin tưởng rằng bạn biết mình đang làm gì. Nhưng MySQL 5.7 cho phép thực thi nghiêm ngặt hơn theo mặc định (điều này có thể được thực hiện ít nghiêm ngặt hơn để hoạt động như các phiên bản trước đó).
Cách khắc phục là tuân theo quy tắc này:Mọi cột trong danh sách lựa chọn của bạn phải thuộc một trong ba trường hợp:
- Cột này nằm trong một hàm tổng hợp như COUNT (), SUM (), MIN, MAX (), AVERAGE () hoặc GROUP_CONCAT ().
- Cột này là một trong (các) cột có tên trong
GROUP BY
mệnh đề. - Cột phụ thuộc về mặt chức năng vào (các) cột có tên trong
GROUP BY
mệnh đề.
Để biết thêm lời giải thích, hãy đọc blog tuyệt vời này: Gỡ bỏ NHÓM THEO huyền thoại
Hãy xem lại nhận xét của bạn, tôi chỉ có thể phỏng đoán vì bạn chưa đăng định nghĩa bảng của mình.
Tôi đoán rằng products_description
và nhà sản xuất manufacturers
phụ thuộc về mặt chức năng vào products
, vì vậy bạn có thể liệt kê chúng như trong danh sách chọn. Nhưng giả định này có thể không đúng, tôi không biết giản đồ của bạn.
Dù sao, lỗi về s.status
nên được giải quyết bằng cách sử dụng một hàm tổng hợp. Tôi đang sử dụng MAX()
làm ví dụ.
SELECT p.*,
pd.*,
m.*,
MAX(IF(s.status, s.specials_new_products_price, NULL))
AS specials_new_products_price,
MAX(IF(s.status, s.specials_new_products_price, p.products_price))
AS final_price
FROM products p
LEFT OUTER JOIN specials s ON p.products_id = s.products_id
INNER JOIN manufacturers m ON p.manufacturers_id = m.manufacturers_id
INNER JOIN products_description pd ON p.products_id = pd.products_id
INNER JOIN products_to_categories p2c ON p.products_id = p2c.products_id
INNER JOIN categories c ON p2c.categories_id = c.categories_id
WHERE p.products_view = 1
AND p.products_status = 1
AND p.products_archive = 0
AND c.virtual_categories = 0
AND pd.language_id = 1
GROUP BY p.products_id;
Tôi cũng đã viết lại sự tham gia của bạn theo cách thích hợp. Nên tránh các phép nối kiểu dấu phẩy.