MYSQL выбор пользователей с конкретными навыками - PullRequest
0 голосов
/ 21 декабря 2009

Я путаюсь с самым сложным SQL-запросом, который я когда-либо делал, что, вероятно, чрезвычайно просто для большинства из вас (:

У меня есть три таблицы: Пользователь, Навыки и Навыки пользователя. Поля которых должны быть достаточно понятны.

Я хочу выбирать людей, у которых есть одно или несколько умений, соответствующих моим критериям.

Я могу выбрать пользователя с навыком, который мне нужен, но я не уверен в синтаксисе запроса нескольких навыков.

Я бы хотел использовать только один запрос, поэтому я пытаюсь использовать GROUP_CONCAT

Вот мой 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

Как ограничить поиск только людьми с навыком 5 И 9?

Ответы [ 5 ]

2 голосов
/ 21 декабря 2009
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

Если вы хотите запретить множественные записи навыков, тогда вам может понадобиться подзапрос

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
0 голосов
/ 23 декабря 2009

Вам просто нужно

HAVING FIND_IN_SET('5', skills) AND FIND_IN_SET('9', skills)

после группировки по (где «умения» - это название сгруппированного столбца). Итак, ваш запрос должен выглядеть как

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)
0 голосов
/ 22 декабря 2009
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
        )

Это зависит от того факта, что (user_id, skill_id) - это клавиша PRIMARY KEY или UNIQUE (то есть вы не можете назначить навык пользователю более одного раза).

Обновление:

Чтобы вернуть все навыки (через запятую):

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
        )
0 голосов
/ 21 декабря 2009

Вот как (даст вам пользователей с навыками 5 И 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
0 голосов
/ 21 декабря 2009

Почему вы не можете просто использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ вместо ЛЕВОГО соединения и ввести предложение WHERE для требуемых навыков?

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
...