2009-09-14 9 views
6

Je travaille sur une demande de réservation d'employé. J'ai deux entités différentes Projets et Utilisateurs auxquels on attribue un nombre variable de Compétences.Comment faire correspondre/comparer des valeurs dans deux resultsets dans SQL Server 2008?

J'ai une table des compétences avec les différentes compétences (colonnes: id, nom) j'enregistrer les compétences des utilisateurs dans une table appelée UserSkills (avec deux colonnes de clé étrangère: fk_user et fk_skill) I enregistrer les compétences du projet dans une autre table appelée ProjectSkills (avec deux colonnes de clé étrangère: fk_project et fk_skill).

Un projet peut exiger peut-être 6 compétences différentes et les utilisateurs lors de l'inscription met également en place leurs compétences. La partie difficile est quand je dois trouver des utilisateurs pour mes projets basés sur leurs qualifications. Je suis seulement intéressé par les utilisateurs qui se rencontrent qui ont toutes les compétences requises par le projet. Les utilisateurs sont autorisés à avoir plus de compétences que nécessaire.

Le code suivant ne fonctionne pas, (et même si elle l'a fait, ne serait pas la performance très sympathique), mais il illustre mon idée:

SELECT * FROM Users u WHERE 
    (SELECT us.fk_skill FROM UserSkills us WHERE us.fk_user = u.id) 
     >= 
    (SELECT ps.fk_skill FROM ProjectSkills ps WHERE ps.fk_project = [some_id]) 

Je pense à faire mon propre fonction qui prend deux tables-variables, puis en établissant la comparaison dans ce genre (une sorte de fonction IN modifiée), mais je préférerais trouver une solution plus performante.

Je développe sur SQL Server 2008.

J'apprécie vraiment des idées ou des suggestions à ce sujet. Merci!

Répondre

6
SELECT * 
FROM Users u 
WHERE NOT EXISTS 
     (
     SELECT NULL 
     FROM ProjectSkill ps 
     WHERE ps.pk_project = @someid 
       AND NOT EXISTS 
       (
       SELECT NULL 
       FROM UserSkills us 
       WHERE us.fk_user = u.id 
         AND us.fk_skill = ps.fk_skill 
       ) 
     ) 
+1

OMG! Vous avez répondu avec la bonne réponse après seulement 2½ minutes! Tu es mon héros! ;) C'était ma première question sur stackoverflow, mais sûrement pas ma dernière ... Merci, votre aide est très appréciée! –

+0

Zounds. Existe-t-il un site Web expliquant et expliquant comment et comment ces sous-requêtes sont corrélées? –

+0

'@Philip Kelley': J'écris actuellement une série d'articles sur' NOT IN' vs 'NOT EXISTS' vs' LEFT JOIN/IS NULL' dans différents 'SGBDR'. – Quassnoi

0
-- Assumes existance of variable @ProjectId, specifying 
-- which project to analyze 
SELECT us.UserId 
from UserSkills us 
    inner join ProjectSkills ps 
    on ps.SkillId = us.SkillId 
    and ps.ProjectId = @ProjectId 
group by us.UserId 
having count(*) = (select count(*) 
        from ProjectSkills 
        where ProjectId = @ProjectId) 

Vous voudriez tester un débogage, comme je n'ai pas de données de test pour l'exécuter à travers. Idem pour l'indexation pour l'optimiser.

(maintenant pour publier et voir si quelqu'un est venu avec une meilleure façon - il devrait y avoir quelque chose de plus subtile et efficace que cela.)

Questions connexes