Pergunta

Estou de longe, estou de longe a consulta SQL mais complexa que já fiz, o que provavelmente é extremamente simples para a maioria de vocês (:

Eu tenho três tabelas, usuário, habilidades e user_skills. Cujos campos devem ser bastante auto -explicativos.

Quero escolher pessoas que tenham uma ou mais habilidades que atendam aos meus critérios.

Posso selecionar um usuário com a habilidade que estou buscando, mas não tenho certeza sobre a sintaxe para consultar várias habilidades.

Eu gostaria de usar apenas uma consulta, então estou tentando usar o group_concat

Aqui está o meu 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

Como limito a pesquisa a apenas pessoas que têm habilidade 5 e 9?

Foi útil?

Solução

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
        )

Isso depende do fato de que (user_id, skill_id) é um PRIMARY KEY ou a UNIQUE chave (ou seja, você não pode atribuir uma habilidade a um usuário mais de uma vez).

Atualizar:

Para devolver todas as habilidades (vírgula separada):

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
        )

Outras dicas

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

Se você deseja evitar vários registros de habilidades, pode precisar de uma subconsulta

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

Por que você não pode simplesmente usar uma junção interna no lugar da junção esquerda e emitir uma cláusula onde as habilidades necessárias?

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

Veja como (dará a você usuários com habilidades 5 e 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

Você só precisa de um

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

Após o grupo (onde "habilidades" é o nome da coluna agrupada). Então sua consulta agora deve parecer

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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top