Kann mir jemand zeigen, warum meine SQL-Abfrage nicht funktioniert (siehe Details)?
-
22-08-2019 - |
Frage
Ich habe die folgende Abfrage Duplikate zu finden:
SELECT userID,
COUNT(userID) AS NumOccurrences
FROM userDepartments
GROUP BY userID
HAVING ( COUNT(userID) > 1 )
Ich habe dann versucht, das Hinzufügen einer innere Verknüpfung, so kann ich die Benutzername sieht, die Übereinstimmen, die in einer anderen Tabelle gespeichert werden.
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 )
Aber es gab mir eine Fehlermeldung, dass users.firstname war nicht Teil einer Aggregatfunktion oder etwas ...
Wer weiß, wie ich die Zählung bekommen kann, zeigt nur Benutzer mit mehr als 1 Abteilung und erhält auch die Vor- und Nachnamen aus der anderen Tabelle, so kann ich eine Liste des Benutzer-Namen erhalten, die mehr als eine Abteilung hat zugewiesen?
EDIT: Dies ist der QUERY, die für mich schließlich arbeitete ...
SELECT firstname, lastname
FROM tbl_users
WHERE (userID IN
(SELECT userID
FROM tbl_usersDepts
GROUP BY userID
HAVING (COUNT(userID) > 1)))
Lösung
Ich würde die Abfrage ein wenig neu ordnen ....
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
Andere Tipps
Der SQL-Engine weiß nicht, dass Sie nur einen Benutzername pro Benutzer-ID haben, so haben Sie zu einer Gruppe von Vornamen und Nachnamen sowie durch Benutzer-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 )
Wenn Sie mit Vornamen und Nachnamen nicht Gruppe zu tun, der Motor nicht weiß, was es tun soll, wenn es für ein bestimmtes Benutzer-ID mehr als einen Wert von Vornamen bekommt. Durch sie zu einer Gruppe von allen drei Werten zu sagen, weiß er, dass, wenn es mehr als eine Zeile pro Benutzer-ID ist, sollte es all diese Zeilen zurück. Auch wenn dies nicht passieren soll, ist der Motor intelligent genug, um in diesem Fall nicht zu, dass selbst auf ihrer entscheiden.
Sie können es auch tun, auf diese Weise:
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
Gruppe von allen drei: die userDepartments.userID, users.firstname und users.lastname
Sie müssen user.firstname und users.lastname in Ihrer GROUP BY-Klausel enthalten - da sie nicht aggregierten Werte sind (beachten Sie, dass MySQL tatsächlich die Syntax unterstützt Sie in Ihrer Abfrage verwendet haben, aber es ist nicht Standard).
Wenn Sie eine „Gruppe von“ tun dann alles in dem „Auswahl“ Teil entweder muss sein:
-
in der erwähnten "Gruppe von" -Klausel oder
-
Das Ergebnis einer Aggregatfunktion (wie count ())
Ich würde es auf diese Weise tut (in Oracle, falls dies in Ihrem System nicht funktioniert):
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
Fügen Sie Ihre user.Firstname und User.lastname zu Ihrer Gruppe durch Klausel
Ich sehe viele gute Hinweise über Ihren Namen Felder der Gruppe Hinzufügen von. Ich glaube, ich würde es so, aber:
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
Ein Grund für diesen Ansatz ist, dass es einfacher macht dann zurück zu gehen und andere Informationen erhalten Sie vielleicht.