Domanda

Ho usato la seguente query per trovare i duplicati:

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

Allora ho provato ad aggiungere un inner join così ho potuto vedere i nomi utente che corrispondono, che sono memorizzati in una tabella diversa.

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 )

Ma mi ha dato un errore dicendo che users.firstname non faceva parte di qualche funzione di aggregazione o qualcosa del genere ...

Qualcuno sa come posso ottenere il conteggio, solo gli utenti spettacolo con più di 1 reparto, e anche ottenere il nome e il cognome fuori all'altro tavolo in modo da poter ottenere un elenco di nomi di utenti che hanno più di un reparto assegnato?

EDIT: Questa è la query che ha finito per lavorare per me ...

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

Soluzione

Vorrei riorganizzare la domanda un po '....

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

Altri suggerimenti

Il motore SQL non sa che hai un solo nome utente per ogni userid, quindi bisogna gruppo dal nome e cognome, nonché dall'utente 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 )

Se non lo fai gruppo per nome e cognome, il motore non si sa che cosa dovrebbe fare se ottiene più di un valore di cognome per un dato userid. Dicendo al gruppo da tutte e tre valori, sa che se v'è più di una riga per userid, dovrebbe restituire tutte le righe. Anche se questo non dovesse accadere, il motore non è abbastanza intelligente, in questo caso a decidere che da sola.

Si potrebbe anche fare in questo modo:

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

Gruppo da parte di tutti e tre: l'userDepartments.userID, users.firstname, e users.lastname

È necessario includere user.firstname e users.lastname nella vostra clausola GROUP BY - in quanto non sono valori aggregati (si noti che MySQL realtà non supporta la sintassi che hai usato nella query, ma non è di serie).

Se si fa un "gruppo da" poi tutto nella parte di "selezionare" o deve essere:

  1. di cui il "gruppo da" clausola o

  2. Il risultato di una funzione di aggregazione (come count ())

Lo farei in questo modo (in Oracle, nel caso in cui questo non funziona nel 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

Aggiungi il tuo user.Firstname e User.lastname al gruppo dalla clausola

Vedo un sacco buone note su come aggiungere i vostri campi di nome al gruppo. Penso che mi piacerebbe fare in questo modo, però:

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 delle ragioni di questo approccio è che rende più facile per poi tornare indietro e prendere qualsiasi altra informazione che si potrebbe desiderare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top