¿Alguien puede demostrar por qué mi consulta SQL no está funcionando (ver detalles)?

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

  •  22-08-2019
  •  | 
  •  

Pregunta

He utilizado la siguiente consulta para encontrar duplicados:

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

Luego trató añadiendo una combinación interna para que pudiera ver los nombres de usuarios que correspondan, que se almacenan en una tabla diferente.

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 )

Pero me dio un error diciendo que users.firstname no era parte de una función agregada o algo ...

¿Alguien sabe cómo puedo obtener el recuento, sólo mostrar a los usuarios con más de 1 departamento, y también obtener el nombre y apellido de la otra tabla para que pueda obtener una lista de los nombres de los usuarios que tienen más de un departamento asignado?

EDITAR: Esta es la consulta que terminó trabajando para mí ...

SELECT     firstname, lastname
FROM         tbl_users
WHERE     (userID IN
                          (SELECT     userID
                            FROM          tbl_usersDepts
                            GROUP BY userID
                            HAVING      (COUNT(userID) > 1)))
¿Fue útil?

Solución

Me reorganizar la consulta un poco ....

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

Otros consejos

El motor de SQL no sabe que sólo tiene un nombre de usuario por ID de usuario, así que hay que agrupar por nombre y apellido, así como por la identificación del usuario.

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 )

Si no lo hace por el grupo nombre y apellido, el motor no se sabe lo que tiene que hacer si se pone más de un valor de Nombre de un id de usuario dado. Al decirle que al grupo por los tres valores, se sabe que si hay más de una fila por cada ID de usuario, se debe devolver todas las filas. A pesar de que esto no debería ocurrir, el motor no es lo suficientemente inteligente como en este caso para decidir que por su propia cuenta.

También puede hacerlo de esta manera:

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

Grupo de los tres: el userDepartments.userID, users.firstname y users.lastname

Es necesario incluir user.firstname y users.lastname en su cláusula GROUP BY - ya que no son valores agregados (tenga en cuenta que MySQL no soporta realmente la sintaxis que se ha utilizado en la consulta, pero no es estándar).

Si lo hace un "grupo por" entonces todo en la parte de "seleccionar" o bien tiene que ser:

  1. mencionado en el "grupo por" cláusula o

  2. El resultado de una función de agregado (como count ())

Me gustaría hacerlo de esta manera (en Oracle, por si acaso esto no funciona en su sistema):

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

Añada su user.Firstname y User.lastname a su grupo por la cláusula

Veo un montón buenas notas acerca de la adición de sus campos de nombre al grupo por. Creo que lo haría así, sin embargo:

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

Una de las razones para este enfoque es que hace que sea más fácil para luego volver y conseguir cualquier otra información que desee.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top