MYSQL Auswahl der Benutzer mit spezifischen Fähigkeiten
-
20-09-2019 - |
Frage
Ich bin muddling meinen Weg durch die mit Abstand komplexeste SQL-Abfrage die ich je gemacht habe, die für die meisten von Ihnen wahrscheinlich sehr einfach (:
habe ich drei Tabellen, Benutzer, Fähigkeiten und User_Skills. Die Felder, von denen sollten ziemlich selbsterklärend.
Ich möchte die Leute wählen, die eine oder mehrere Fähigkeiten, die meine Kriterien erfüllen.
Ich kann einen Benutzer auswählen, mit der Fähigkeit, die ich nach bin, aber ich bin nicht sicher über die Syntax für mehrere Fähigkeiten abfragt.
Ich möchte nur eine Abfrage verwenden, so dass ich zu verwenden GROUP_CONCAT bin versucht,
Hier ist mein SQL:
SELECT User_id, first_name, last_name, county, GROUP_CONCAT(CAST(Skill_id AS CHAR))
FROM User LEFT JOIN User_Skills ON User.id = User_Skills.User_id
LEFT JOIN Skills ON User_Skills.Skill_id = Skills.id GROUP BY User_id
User_id first_name last_name county GROUP_CONCAT(CAST(Skill_id AS CHAR))
1000 Joe Blow West Yorkshire 8,6,1,9,7,3,5,10
1001 Fred Bloggs COUNTY1 5,8,2,7,9
1003 asdf asdf1 Some County 10,8,2
Wie begrenzen wir die Suche nur Menschen, die Fähigkeit haben, 5 und 9?
Lösung
SELECT *
FROM users u
WHERE EXISTS
(
SELECT NULL
FROM user_skills us
WHERE us.skill_id IN (5, 9)
AND us.user_id = u.id
LIMIT 1, 1
)
Dies beruht auf der Tatsache, dass (user_id, skill_id)
ist ein PRIMARY KEY
oder ein UNIQUE
Schlüssel (die Sie nicht eine Fähigkeit für einen Benutzer mehr als einmal zuweisen können, ist).
Update:
alle Fähigkeiten zurückzukehren (durch Komma getrennt):
SELECT u.*,
(
SELECT GROUP_CONCAT(skill_id)
FROM user_skills uso
WHERE uso.user_ud = u.user_id
) AS all_skills
FROM users u
WHERE EXISTS
(
SELECT NULL
FROM user_skills us
WHERE us.skill_id IN (5, 9)
AND us.user_id = u.id
LIMIT 1, 1
)
Andere Tipps
SELECT User_id, first_name, last_name, county, GROUP_CONCAT(CAST(Skill_id AS CHAR))
FROM User JOIN User_Skills ON User.id = User_Skills.User_id
JOIN Skills ON User_Skills.Skill_id IN (5,9)
GROUP BY User_id
Wenn Sie mehrere Fähigkeiten Aufzeichnungen verhindern wollen, dann müssen Sie eine Unterabfrage
SELECT User_id, first_name, last_name, county,
(
SELECT (GROUP_CONCAT(CAST(subSkill.Skill_id AS CHAR))
FROM Skills as subSkill WHERE subSkill.skill_id = User_Skills.skill_id
GROUP BY subSkill.skill_id
)
FROM User JOIN User_Skills ON User.id = User_Skills.User_id
JOIN Skills ON User_Skills.Skill_id IN (5,9)
GROUP BY User_id
Warum kann man einfach nicht verwenden ein INNER JOIN Inplace der LINKEN beizutreten, und geben Sie eine WHERE-Klausel für die erforderlichen Fähigkeiten?
SELECT User_id, first_name, last_name, county, GROUP_CONCAT(CAST(Skill_id AS CHAR))
FROM User
INNER JOIN User_Skills ON User.id = User_Skills.User_id
INNER JOIN Skills ON User_Skills.Skill_id = Skills.id GROUP BY User_id
WHERE skill_id = 5 OR skill_id=9
Hier ist, wie (geben Sie den Benutzern mit Fähigkeiten 5 und 9):
SELECT User_id, first_name, last_name, county FROM User INNER JOIN User_Skills ON User.id = User_Skills.User_id INNER JOIN Skills ON User_Skills.Skill_id = Skills.id WHERE Skills.Skill_id = 5 AND Skills.Skill_id = 9 GROUP BY User_id
Sie brauchen nur ein
HAVING FIND_IN_SET('5', skills) AND FIND_IN_SET('9', skills)
nach der Gruppe (wobei „Fähigkeiten“ ist der Name der gruppierten Spalte). So Ihre Abfrage sollte jetzt aussehen
SELECT User_id, first_name, last_name, county, GROUP_CONCAT(CAST(Skill_id AS CHAR)) as skills
FROM User LEFT JOIN User_Skills ON User.id = User_Skills.User_id
LEFT JOIN Skills ON User_Skills.Skill_id = Skills.id GROUP BY User_id
HAVING FIND_IN_SET('5', skills) AND FIND_IN_SET('9', skills)