Dodałbym po prostu group_id
do GROUP BY
.
Kiedy SELECT
ing kolumny, która nie jest częścią GROUP BY
może istnieć wiele wartości dla tej kolumny w grupach, ale w wynikach będzie miejsce tylko na pojedynczą wartość. Tak więc baza danych zazwyczaj należy dokładnie powiedzieć, jak przekształcić te wiele wartości w jedną wartość. Zwykle odbywa się to za pomocą funkcji agregującej, takiej jak COUNT()
, SUM()
, MAX()
itp... mówię zazwyczaj ponieważ większość innych popularnych systemów baz danych nalega na to. Jednak w MySQL przed wersją 5.7 domyślne zachowanie było bardziej wyrozumiałe, ponieważ nie narzekał, a następnie arbitralnie wybierał dowolną wartość ! Ma również ANY_VALUE()
funkcja, która może być wykorzystana jako inne rozwiązanie tego pytania, jeśli naprawdę potrzebujesz tego samego zachowania, co wcześniej. Ta elastyczność ma swoją cenę, ponieważ nie jest deterministyczna, więc nie polecałbym jej, chyba że masz bardzo dobry powód, by jej potrzebować. MySQL włącza teraz only_full_group_by
ustawienie domyślne z ważnych powodów, więc najlepiej jest się do tego przyzwyczaić i zadbać o to, by zapytania były z nim zgodne.
Dlaczego więc moja prosta odpowiedź powyżej? Postawiłem kilka założeń:
1) group_id
jest unikalny. Wydaje się rozsądne, w końcu jest to „identyfikator”.
2) group_name
jest również wyjątkowy. To może nie być takie rozsądne założenie. Jeśli tak nie jest i masz zduplikowane group_names
a następnie postępuj zgodnie z moją radą, aby dodać group_id
do GROUP BY
, może się okazać, że otrzymujesz teraz więcej wyników niż wcześniej, ponieważ grupy o tej samej nazwie będą teraz miały osobne wiersze w wynikach. Dla mnie byłoby to lepsze niż ukrywanie tych zduplikowanych grup, ponieważ baza danych po cichu arbitralnie wybrała wartość!
Dobrą praktyką jest również zakwalifikowanie wszystkich kolumn za pomocą ich nazwy tabeli lub aliasu, gdy zaangażowanych jest więcej niż jedna tabela...
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