Кто-нибудь может показать мне, почему мой SQL-запрос не работает (см. Подробности)?

StackOverflow https://stackoverflow.com/questions/522105

  •  22-08-2019
  •  | 
  •  

Вопрос

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

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 не был частью какой-то агрегатной функции или чего-то в этом роде...

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

Редактировать:ЭТО ЗАПРОС, КОТОРЫЙ В КОНЕЧНОМ ИТОГЕ СРАБОТАЛ У МЕНЯ...

SELECT     firstname, lastname
FROM         tbl_users
WHERE     (userID IN
                          (SELECT     userID
                            FROM          tbl_usersDepts
                            GROUP BY userID
                            HAVING      (COUNT(userID) > 1)))
Это было полезно?

Решение

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

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

Другие советы

Движок 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 )

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

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

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

Сгруппироваться по всем трем:userDepartments.Идентификатор пользователя, users.firstname и users.lastname

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

Если вы выполняете "группировку по", то все в части "выбрать" либо должно быть:

  1. Упомянуто в предложении "группировать по" или

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

Я бы сделал это таким образом (в 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

Добавьте вашего пользователя.Firstname и User.lastname в ваше предложение group by

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top