Может кто-нибудь показать мне, почему мой SQL-запрос не работает (см. Подробности)? - PullRequest
0 голосов
/ 06 февраля 2009

Я использовал следующий запрос для поиска дубликатов:

SELECT userID,
COUNT(userID) AS NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING ( COUNT(userID) > 1 )

Затем я попытался добавить внутреннее объединение, чтобы увидеть совпадающие имена пользователей, которые хранятся в другой таблице.

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 )

Но это дало мне ошибку, сказав, что users.firstname не было частью какой-то агрегатной функции или чего-то ...

Кто-нибудь знает, как я могу получить счетчик, показывать только пользователей с более чем одним отделом, а также получать имя и фамилию из другой таблицы, чтобы я мог получить список имен пользователей, имеющих более одного отдела назначен?

РЕДАКТИРОВАТЬ: ЭТО ЗАПРОС, КОТОРЫЙ ЗАВЕРШЕН, РАБОТАЯ ДЛЯ МЕНЯ ...

SELECT     firstname, lastname
FROM         tbl_users
WHERE     (userID IN
                          (SELECT     userID
                            FROM          tbl_usersDepts
                            GROUP BY userID
                            HAVING      (COUNT(userID) > 1)))

Ответы [ 8 ]

5 голосов
/ 06 февраля 2009

Я бы немного переставил запрос ....

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
2 голосов
/ 06 февраля 2009

Механизм SQL не знает, что у вас есть только одно имя пользователя на идентификатор пользователя, поэтому вам нужно сгруппировать по имени и фамилии, а также по идентификатору пользователя.

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 )

Если вы не группируете по имени и фамилии, движок не знает, что он должен делать, если он получает более одного значения имени для данного идентификатора пользователя. Говоря ему сгруппировать по всем трем значениям, он знает, что если существует более одной строки на идентификатор пользователя, он должен вернуть все эти строки. Несмотря на то, что это не должно происходить, двигатель в этом случае не достаточно умен, чтобы решить это самостоятельно.

Вы также можете сделать это следующим образом:

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
1 голос
/ 06 февраля 2009

Группировка по всем трем: userDepartments.userID, users.firstname и users.lastname

0 голосов
/ 07 февраля 2009

Добавьте ваше user.Firstname и User.lastname в вашу группу по предложению

0 голосов
/ 06 февраля 2009

Я вижу много хороших заметок о добавлении полей вашего имени в группу. Я думаю, что сделал бы это так, хотя:

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

Одна из причин такого подхода состоит в том, что он упрощает возврат и получение любой другой информации, которая вам может понадобиться.

0 голосов
/ 06 февраля 2009

Я бы сделал это следующим образом (в Oracle, на случай, если это не сработает в вашей системе):

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
0 голосов
/ 06 февраля 2009

Если вы сделаете «group by», тогда все в части «select» должно быть:

  1. Упоминается в предложении "group by" или

  2. Результат агрегатной функции (например, count ())

0 голосов
/ 06 февраля 2009

Вам необходимо включить user.firstname и users.lastname в ваше предложение GROUP BY - поскольку они не являются агрегированными значениями (обратите внимание, что MySQL действительно поддерживает синтаксис, который вы использовали в своем запросе, но он не является стандартным).

...