Reputation: 43813
I used the following query to find duplicates:
SELECT userID,
COUNT(userID) AS NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING ( COUNT(userID) > 1 )
I then tried adding an inner join so I could see the user names that match, which are stored in a different table.
SELECT userDepartments.userID, users.firstname, users.lastname,
COUNT(userID) AS NumOccurrences
FROM userDepartments INNER JOIN users ON userDepartments.userID = users.userID
GROUP BY userID
HAVING ( COUNT(userID) > 1 )
But it gave me an error saying that users.firstname was not part of some aggregate function or something...
Does anyone know how I can get the count, only show users with more than 1 department, and also get the first and last name out of the other table so I can get a list of users names who have more than one department assigned?
EDIT: THIS IS THE QUERY THAT ENDED UP WORKING FOR ME...
SELECT firstname, lastname
FROM tbl_users
WHERE (userID IN
(SELECT userID
FROM tbl_usersDepts
GROUP BY userID
HAVING (COUNT(userID) > 1)))
Upvotes: 0
Views: 1098
Reputation: 415690
I see a lot good notes about adding your name fields to the group by. I think I'd do it like this, though:
SELECT Users.*, dups.NumOccurances, ud.DepartmentName
FROM Users
INNER JOIN
(
SELECT userID, COUNT(userID) AS NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING ( COUNT(userID) > 1 )
) dups ON dups.userID = Users.UserID
INNER JOIN userDepartments ud ON ud.UserID=Users.UserID
ORDER BY Users.LastName, Users.FirstName, Users.UserID
One reason for this approach is that it makes it easier to then go back and get any other information you might want.
Upvotes: 0
Reputation: 45493
The SQL engine doesn't know that you only have one username per userid, so you have to group by firstname and lastname as well as by user id.
SELECT userDepartments.userID, users.firstname, users.lastname,
COUNT(userID) AS NumOccurrences
FROM userDepartments INNER JOIN users ON userDepartments.userID = users.userID
GROUP BY userID, users.firstname, users.lastname
HAVING ( COUNT(userID) > 1 )
If you don't group by firstname and lastname, the engine doesn't know what it's supposed to do if it gets more than one value of firstname for a given userid. By telling it to group by all three values, it knows that if there is more than one row per userid, it should return all those rows. Even though this shouldn't happen, the engine isn't smart enough in this case to decide that on its own.
You could also do it this way:
SELECT users.userId, users.firstname, users.lastname, departments.NumOccurrences
FROM users INNER JOIN (
SELECT userId, count(userId) as NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING ( COUNT(userID) > 1 )
) departments ON departments.userID = users.userID
Upvotes: 2
Reputation: 48111
I would do it this way (in Oracle, just in case this doesn't work in your system):
SELECT users.userID, users.firstname, users.lastname, NumOccurrences
FROM users
INNER JOIN (
SELECT userID, COUNT(userID) AS NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING ( COUNT(userID) > 1 )
) d
ON d.userID = users.userID
Upvotes: 0
Reputation: 65435
I would rearrange the query a little bit....
SELECT
duplicates.NumOccurrences,
duplicates.userID,
users.firstname,
users.lastname
FROM (
SELECT
userID,
COUNT(userID) AS NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING COUNT(userID) > 1
) duplicates
INNER JOIN users ON duplicates.userID = users.userID
Upvotes: 5
Reputation: 13159
If you do a "group by" then everything in the "select" portion either needs to be:
Mentioned in the "group by" clause or
The result of an aggregate function (like count())
Upvotes: 0
Reputation: 8382
You need to include user.firstname and users.lastname in your GROUP BY clause - as they are not aggregate values (note that MySQL does actually support the syntax you've used in your query, but it is not standard).
Upvotes: 0
Reputation: 11678
Group by all three: the userDepartments.userID, users.firstname, and users.lastname
Upvotes: 1