Pregunta

Estoy lidiando con la consulta SQL más compleja que he hecho jamás, que probablemente sea extremadamente simple para la mayoría de ustedes (:

Tengo tres tablas, Usuario, Habilidades y User_Skills.cuyos campos deberían explicarse por sí solos.

Quiero elegir personas que tengan una o más habilidades que cumplan con mis criterios.

Puedo seleccionar un usuario con la habilidad que busco, pero no estoy seguro de la sintaxis para consultar múltiples habilidades.

Me gustaría usar solo una consulta, así que estoy intentando usar GROUP_CONCAT

Aquí está mi 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

¿Cómo limito la búsqueda solo a personas que tengan las habilidades 5 y 9?

¿Fue útil?

Solución

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
        )

Esto se basa en el hecho de que es un (user_id, skill_id) PRIMARY KEY o una llave UNIQUE (es decir no se puede asignar una habilidad a un usuario más de una vez).

Actualización:

Para devolver todas las habilidades (separados por comas):

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
        )

Otros consejos

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

Si desea evitar múltiples registros de habilidades, es posible que necesite una 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 qué no puede usted sólo tiene que utilizar un INNER JOIN in-situ de la combinación izquierda, y emitir una cláusula WHERE de las habilidades requeridas?

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

Así es como (que dará a los usuarios con habilidades 5 y 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

Sólo se necesita un

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

después de que el grupo por (donde "habilidades" es el nombre de la columna agrupado). Así que la consulta debe parecerse

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top