SQL:如何跟踪已在相关子查询中匹配的行?

时间:2009-09-14 19:28:23

标签: sql tsql sql-server-2008

这对你来说是另一个挑战SQL-gurus ...

我在这里写了另一个关于匹配两个结果集(How to match/compare values in two resultsets in SQL Server 2008?)的问题。这个问题是问答的续集,但由于它是一个不同的主题,我将其作为一个新问题创建。

Quassnoi建议以下解决方案来选择满足给定项目所需技能的所有用户:

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

这很有效。但是,如果我想创建一个查询,列出特定日期的所有项目,包括最佳匹配用户,该怎么办?我想象以下格式:

projectid        userid
----------       -----------
1                1234
2                5678
3                4321
4                8765

重要的是,用户只能在列表中建议一次! ...因为项目是在同一天,用户不能再预订。

现在,我可以想象一些SQL:

SELECT p.id 'projectid', ( SELECT TOP 1 u.id 
        FROM   Users u  
        WHERE  NOT EXISTS 
        ( 
             SELECT  NULL  
             FROM    ProjectSkill ps        
             WHERE   ps.pk_project = p.id 
             AND NOT EXISTS  
                 (                
          SELECT  NULL                
          FROM    UserSkills us                
          WHERE   us.fk_user = u.id                        
                 AND us.fk_skill = ps.fk_skill               
         )        
         )
         ORDER BY rating DESC
      ) 'userid'
FROM Projects p 
WHERE startdate > @beginningofday 
      AND startdate < @endofday

但是这(显然)很高兴地一次又一次地向同一个用户提出建议,只要他具备项目所需的技能。

是否有人建议如何跟踪Users表中哪些行已经在查询中先前匹配?使用变量可能吗?还是有另外一种聪明的方法可以解决这个问题吗?

查询必须在SQL Server 2008上运行。

任何帮助将不胜感激!感谢。

此致 亚历

3 个答案:

答案 0 :(得分:1)

您的任务是rooks problem的经典示例。

SQL无法有效解决。

如果您的员工可能具备所需技能(例如,非熟练工人是一种罕见的例外而非规则),有一些简单的算法可以很好地运作。

但是,您最好使用SQL来检索限制,即。即哪些用户适合(或不适合)哪些项目,并将其提供给启发式算法。

答案 1 :(得分:0)

已经很长时间了,但我实际上认为游标(我讨厌游标 - 它们通常使用错误)可以在这里提供帮助。

您可以考虑的另一件事是用户实际上必须预订一天。这样一来,“建议的用户”可以在几个项目中出现,因为还没有最终的结果。此外,我建议一个项目的用户多一个,所以分配他们的人可以选择最合理的。

实际上,在项目上预订用户也可以在将来消除一些混乱。如果用户正在改变他的技能,查询结果可能会发生变化。

如果您使用的是指定的,那么您的用例会更加清晰

答案 2 :(得分:0)

这包含旅行商问题的阴影 - 如何在X个项目中最佳地适应N个用户(特别是如果您正在为每个项目寻找最佳/最合适的用户)。如果N和X的值足够大,问题就会变得无法解决(即在你的生命中你不会解决它)。

这无疑是一个极端的例子。即便如此,当您尝试为流程添加越来越多的功能时,我可以看到需求不断膨胀。我的观点是,您尝试解决的问题在T-SQL中可能无法合理解决,更不用说单个查询了。为每个项目制作推荐用户列表并让某人做出最终决定可能是明智之举。