Quelqu'un peut-il me montrer pourquoi ma requête SQL ne fonctionne pas (voir les détails)?
-
22-08-2019 - |
Question
je la requête suivante pour trouver des doublons:
SELECT userID,
COUNT(userID) AS NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING ( COUNT(userID) > 1 )
Je puis essayé d'ajouter une jointure interne que je puisse voir les noms d'utilisateur qui correspondent, qui sont stockés dans une autre table.
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 )
Mais il m'a donné une erreur en disant que users.firstname ne faisait pas partie d'une fonction globale ou quelque chose ...
Quelqu'un sait comment je peux obtenir le nombre, seuls les utilisateurs de spectacle avec plus de 1 département, et aussi obtenir le premier et le dernier nom de l'autre table que je peux obtenir une liste des noms des utilisateurs qui ont plus d'un ministère attribué?
EDIT: CECI EST LE QUERY qui a fini de travailler pour moi ...
SELECT firstname, lastname
FROM tbl_users
WHERE (userID IN
(SELECT userID
FROM tbl_usersDepts
GROUP BY userID
HAVING (COUNT(userID) > 1)))
La solution
Je réorganiser la requête un peu ....
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
Autres conseils
Le moteur SQL ne sait pas que vous avez seulement un nom d'utilisateur par code d'utilisateur, de sorte que vous devez regrouper par prenom et nomFamille ainsi que par ID utilisateur.
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 vous ne le faites pas par groupe et prenom lastname, le moteur ne sait pas ce qu'il est censé faire si elle obtient plus d'une valeur de prenom pour une donnée userid. En disant à un groupe par les trois valeurs, il sait que s'il y a plus d'une ligne par code d'utilisateur, il doit retourner toutes les lignes. Même si cela ne devrait pas arriver, le moteur est pas assez intelligent dans ce cas, de décider que lui-même.
Vous pouvez aussi le faire de cette façon:
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
Groupe par les trois: la userDepartments.userID, users.firstname et users.lastname
Vous devez inclure user.firstname et users.lastname dans votre clause GROUP BY - car ils ne sont pas des valeurs agrégées (notez que MySQL ne supporte effectivement la syntaxe que vous avez utilisé dans votre requête, mais ce ne sont pas standard).
Si vous faites alors « groupe par » tout dans la partie « select » doit soit être:
-
a mentionné dans le "groupe par" clause ou
-
Le résultat d'une fonction d'agrégation (comme count ())
Je le ferais de cette façon (dans Oracle, juste au cas où cela ne fonctionne pas dans votre système):
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
Ajoutez votre user.Firstname et user.lastName à votre groupe par clause
Je vois beaucoup de bonnes notes sur l'ajout de vos champs de nom au groupe par. Je pense que je le ferais comme ça, si:
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
L'une des raisons de cette approche est qu'il est plus facile de puis revenir en arrière et obtenir toute autre information que vous voudrez peut-être.