Tôi chỉ thêm group_id
vào GROUP BY
.
Khi SELECT
nhập một cột không phải là một phần của GROUP BY
có thể có nhiều giá trị cho cột đó trong các nhóm, nhưng sẽ chỉ có khoảng trống cho một giá trị duy nhất trong kết quả. Vì vậy, cơ sở dữ liệu thường cần được chỉ dẫn chính xác cách biến nhiều giá trị đó thành một giá trị. Thông thường, điều này được thực hiện với một hàm tổng hợp như COUNT()
, SUM()
, MAX()
v.v ... Tôi nói thường bởi vì hầu hết các hệ thống cơ sở dữ liệu phổ biến khác nhấn mạnh vào điều này. Tuy nhiên, trong MySQL trước phiên bản 5.7, hành vi mặc định đã được tha thứ hơn vì nó sẽ không phàn nàn và sau đó tùy ý chọn bất kỳ giá trị nào ! Nó cũng có ANY_VALUE()
có thể được sử dụng như một giải pháp khác cho câu hỏi này nếu bạn thực sự cần hành vi tương tự như trước đây. Tính linh hoạt này phải trả giá vì nó không mang tính xác định, vì vậy tôi sẽ không đề xuất nó trừ khi bạn có lý do chính đáng để cần nó. MySQL hiện đang bật only_full_group_by
cài đặt theo mặc định vì những lý do chính đáng, vì vậy tốt nhất bạn nên làm quen với nó và làm cho các truy vấn của bạn tuân thủ nó.
Vậy tại sao câu trả lời đơn giản của tôi ở trên? Tôi đã đưa ra một số giả định:
1) group_id
là duy nhất. Có vẻ hợp lý, đó là một 'ID'.
2) group_name
cũng là duy nhất. Đây có thể không phải là một giả định hợp lý. Nếu không đúng như vậy và bạn có một số group_names
trùng lặp và sau đó bạn làm theo lời khuyên của tôi để thêm group_id
vào GROUP BY
, bạn có thể thấy rằng bây giờ bạn nhận được nhiều kết quả hơn trước vì các nhóm có cùng tên bây giờ sẽ có các hàng riêng biệt trong kết quả. Đối với tôi, điều này sẽ tốt hơn việc ẩn các nhóm trùng lặp này bởi vì cơ sở dữ liệu đã lặng lẽ chọn một giá trị một cách tùy ý!
Một phương pháp hay nữa là đủ điều kiện cho tất cả các cột có tên bảng hoặc bí danh của chúng khi có nhiều hơn một bảng liên quan ...
SELECT
g.group_id AS 'value',
g.group_name AS 'text'
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id
WHERE g.active = 1
AND g.department_id = 1
AND g.manage_work_orders = 1
AND g.group_name != 'root'
AND g.group_name != 'superuser'
GROUP BY
g.group_name,
g.group_id
HAVING COUNT(d.user_id) > 0
ORDER BY g.group_name