2009-09-14 4 views
6

Ich arbeite an einer Mitarbeiterbuchungsanwendung. Ich habe zwei verschiedene Entitäten Projekte und Benutzer, die beide eine variable Anzahl von Skills haben.Wie Vergleichen/Vergleichen von Werten in zwei Resultsets in SQL Server 2008?

ich Fähigkeiten Tabelle mit den verschiedenen Fähigkeiten haben (Spalten: id, name) ich die Anwenderkenntnisse in einer Tabelle namens UserSkills registrieren (mit zwei Fremdschlüsselspalten: fk_user und fk_skill) ich die Projekt Fähigkeiten registrieren in einer anderen Tabelle namens ProjectSkills (mit zwei Fremdschlüsselspalten: fk_project und fk_skill).

Ein Projekt kann vielleicht 6 verschiedene Fähigkeiten und Benutzer erfordern, wenn die Registrierung auch ihre Fähigkeiten einrichtet.

Der schwierige Teil ist, wenn ich Benutzer für meine Projekte basierend auf ihren Fähigkeiten finden muss. Ich bin nur an Benutzern interessiert, die alle Fähigkeiten haben, die das Projekt erfordert. Den Benutzern wird erlaubt, dass sie qualifizierter sind, als sie benötigen.

Der folgende Code wird nicht funktionieren, (und selbst wenn es tat nicht sehr freundlich Leistung), aber es zeigt meine Idee:

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]) 

Ich denke an meine eigene Funktion zu machen, die nimmt zwei TABLE-Variablen, und dann den Vergleich darin ausarbeiten (Art einer modifizierten IN-Funktion), aber ich würde eher eine Lösung finden, die leistungsfreundlicher ist.

Ich entwickle auf SQL Server 2008

ich wirklich irgendwelche Ideen oder Anregungen zu diesem Thema zu schätzen wissen. Vielen Dank!

Antwort

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! Du hast nach nur 2½ Minuten mit der richtigen Antwort geantwortet! Sie sind mein Held! ;) Das war meine erste Frage zu stackoverflow, aber sicher nicht meine letzte ... Danke, deine Hilfe wird sehr geschätzt! –

+0

Zounds. Gibt es irgendwo eine Website, die das Wie und Warum hinter dieser Verwendung korrelierter Unterabfragen beschreibt und verdeutlicht? –

+0

'@Philip Kelley': Ich schreibe gerade eine Reihe von Artikeln über' NOT IN' vs 'NOT EXISTS' vs' LINKE JOIN/IS NULL' in verschiedenen 'RDBMS's. – 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) 

Sie würden wollen dies eine Debug testen, da ich keine Testdaten haben, es zu durchlaufen. Dito für die Indexierung, um es zu optimieren.

(jetzt zu schreiben, und sehen, ob jemand mit einem besseren Weg kommen wird - sollte es etwas subtiler und wirksamer als das sein.)