Alguém pode me mostrar porque minha consulta SQL não está funcionando (ver detalhes)?

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

  •  22-08-2019
  •  | 
  •  

Pergunta

Eu usei a seguinte consulta para encontrar duplicatas:

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

Então eu tentei adicionar uma junção interna para que eu pudesse ver os nomes de usuário que jogo, que são armazenadas em uma tabela 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 )

Mas deu-me um erro dizendo que users.firstname não fazia parte de alguma função agregada ou algo assim ...

Alguém sabe como posso obter a contagem, mostram apenas usuários com mais de 1 departamento, e também obter o primeiro e último nome de outra mesa para que eu possa obter uma lista de usuários nomes que têm mais de um departamento atribuído?

EDIT: Esta é a consulta que acabou trabalhando para ME ...

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

Solução

Gostaria de reorganizar a consulta um pouco ....

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

Outras dicas

O motor de SQL não sabe que você só tem um nome de usuário por ID de usuário, então você tem que grupo por nome e sobrenome, bem como pela identificação de usuário.

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 )

Se você não agrupar por nome e sobrenome, o motor não sabe o que é suposto fazer se ficar mais de um valor de firstname para um determinado ID de usuário. Ao dizer isso com o grupo por todos os três valores, ele sabe que, se houver mais de uma linha por ID de usuário, ele deve retornar todas as linhas. Mesmo que isso não deve acontecer, o motor não é inteligente o suficiente neste caso para decidir que por conta própria.

Você também pode fazê-lo desta maneira:

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 por todos os três: o userDepartments.userID, users.firstname e users.lastname

Você precisa incluir user.firstname e users.lastname em sua cláusula GROUP BY - como eles não são valores agregados (note que o MySQL faz realmente apoiar a sintaxe que você usou em sua consulta, mas não é padrão).

Se você fizer um "grupo por" tudo depois em "selecionar" parte ou precisa ser:

  1. Mencionado no "grupo por" cláusula ou

  2. O resultado de uma função de agregação (como contagem ())

Gostaria de fazê-lo desta maneira (em Oracle, apenas no caso de isso não funcionar no seu 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

Adicionar uma user.Firstname e user.lastName ao seu grupo pela cláusula

Eu vejo um monte boas notas sobre adicionando seus campos de nome ao grupo por. Eu acho que eu faria isso como este, no entanto:

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

Uma das razões para esta abordagem é que ela torna mais fácil, em seguida, voltar e qualquer outra informação que você pode querer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top