Question

J'embrouillant mon chemin à travers de loin la requête SQL les plus complexes que j'ai jamais fait, ce qui est probablement extrêmement simple pour la plupart d'entre vous (:

J'ai trois tableaux, l'utilisateur, des compétences et User_Skills. Les champs dont devrait être assez explicite.

Je veux choisir les personnes qui ont une ou plusieurs compétences qui répondent à mes critères.

Je peux sélectionner un utilisateur avec la compétence que je suis après, mais je ne suis pas sûr de la syntaxe pour effectuer des requêtes multiples compétences.

Je voudrais simplement utiliser une requête, donc je suis en train d'utiliser GROUP_CONCAT

Voici mon 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

Comment puis-je limiter la recherche aux seules personnes qui ont des compétences 5 et 9?

Était-ce utile?

La solution

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
        )

Cela repose sur le fait que (user_id, skill_id) est un PRIMARY KEY ou une clé UNIQUE (qui vous ne pouvez pas attribuer une compétence à un utilisateur plus d'une fois).

Mise à jour:

Pour revenir toutes les compétences (séparées par des virgules):

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
        )

Autres conseils

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 vous voulez éviter plusieurs enregistrements de compétences, alors vous devrez peut-être un sous-requête

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

Pourquoi ne pouvez-vous utiliser juste un INNER JOIN enplace de la jointure gauche, et émettre une clause WHERE pour les compétences requises?

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

Voilà comment (vous donnera aux utilisateurs des compétences 5 et 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

Vous avez juste besoin d'un

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

après que le groupe par (où « compétences » est le nom de la colonne groupée). Donc, votre requête devrait ressembler à

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top