Jeg ville bare tilføje group_id
til GROUP BY
.
Når SELECT
en kolonne, der ikke er en del af GROUP BY
der kan være flere værdier for den kolonne i grupperne, men der vil kun være plads til en enkelt værdi i resultaterne. Så databasen normalt skal fortælles præcis, hvordan man laver disse flere værdier til én værdi. Normalt gøres dette med en aggregeret funktion som COUNT()
, SUM()
, MAX()
osv... Jeg siger normalt fordi de fleste andre populære databasesystemer insisterer på dette. Men i MySQL før version 5.7 har standardadfærden været mere tilgivende, fordi den ikke vil klage og derefter vilkårligt vælge en hvilken som helst værdi ! Den har også en ANY_VALUE()
funktion, der kunne bruges som en anden løsning på dette spørgsmål, hvis du virkelig havde brug for den samme adfærd som før. Denne fleksibilitet har en pris, fordi den er ikke-deterministisk, så jeg vil ikke anbefale den, medmindre du har en meget god grund til at have brug for den. MySQL aktiverer nu only_full_group_by
indstilling som standard af gode grunde, så det er bedst at vænne sig til det og få dine forespørgsler til at overholde det.
Så hvorfor mit enkle svar ovenfor? Jeg har lavet et par antagelser:
1) group_id
er unik. Det virker rimeligt, det er trods alt et 'ID'.
2) group_name
er også unik. Dette er måske ikke sådan en rimelig antagelse. Hvis dette ikke er tilfældet, og du har nogle dublerede group_names
og så følger du mit råd om at tilføje group_id
til GROUP BY
, kan du opleve, at du nu får flere resultater end tidligere, fordi grupperne med samme navn nu vil have separate rækker i resultaterne. For mig ville dette være bedre end at have disse duplikerede grupper skjult, fordi databasen stille og roligt har valgt en værdi vilkårligt!
Det er også god praksis at kvalificere alle kolonnerne med deres tabelnavn eller alias, når der er mere end én tabel involveret...
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