2009-09-14 19 views
6

Estoy trabajando en una aplicación de reserva de empleados. Tengo dos entidades diferentes, Proyectos y Usuarios a los que se les asigna un número variable de Habilidades.¿Cómo hacer coincidir/comparar valores en dos conjuntos de resultados en SQL Server 2008?

Tengo una mesa de competencias con las diversas habilidades (columnas: id, nombre) me registro de las habilidades de los usuarios en una tabla llamada UserSkills (con dos columnas de clave externa: fk_user y fk_skill) me registro de las habilidades de proyectos en otra tabla llamada ProjectSkills (con dos columnas de clave foránea: fk_project y fk_skill).

Un proyecto puede requerir tal vez 6 habilidades diferentes y los usuarios al registrarse también configuran sus habilidades.

La parte difícil es cuando tengo que encontrar usuarios para mis proyectos en función de sus habilidades. Solo me interesan los usuarios que cumplen con TODAS las habilidades requeridas por el proyecto. A los usuarios se les permite tener más habilidades que las requeridas.

El siguiente código no funcionará, (e incluso si lo hiciera, no sería muy amigable rendimiento), pero ilustra mi idea:

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

estoy pensando en hacer mi propia función que toma dos variables TABLE, y luego trabajar la comparación en eso (tipo de una función IN modificada), pero prefiero encontrar una solución que sea más amigable para el rendimiento.

estoy desarrollando en SQL Server 2008.

Realmente aprecio cualquier idea o sugerencia acerca de esto. ¡Gracias!

Respuesta

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! ¡Respondió con la respuesta correcta después de solo 2 minutos y medio! ¡Eres mi héroe! ;) Esta fue mi primera pregunta sobre stackoverflow, pero seguramente no es la última ... ¡Gracias, su ayuda es muy apreciada! –

+0

Zounds. ¿Existe un sitio web en algún lugar que especifique y aclara los cómo y por qué detrás de este uso de subconsultas correlacionadas? –

+0

'@Philip Kelley': Actualmente estoy escribiendo una serie de artículos sobre' NOT IN' vs 'NOT EXISTS' vs' LEFT JOIN/IS NULL' en diferentes 'RDBMS'. – 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) 

te gustaría probar una depuración esto, como no tengo datos de prueba para ejecutar a través. Lo mismo para la indexación para optimizarlo.

(ahora para publicar y ver si alguien ha surgido con una mejor manera - no debe ser algo más sutil y eficaz que esto.)

Cuestiones relacionadas