代码之家  ›  专栏  ›  技术社区  ›  Alex

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

  •  4
  • Alex  · 技术社区  · 15 年前

    这对你来说是另一个挑战,SQL专家…

    我在这里写了另一个关于匹配两个结果集的问题( 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
    

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

    是否有人建议如何跟踪用户表中哪些行在查询的早期已经匹配?可能使用变量?或者有没有其他聪明的方法来解决这个问题?

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

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

    当做 亚历克斯

    3 回复  |  直到 15 年前
        1
  •  1
  •   Quassnoi    15 年前

    你的任务是 rooks problem .

    它不能有效地解决 SQL .

    有一些简单的算法可以很好地工作,如果您的工人可能需要技能(即,一个非熟练工人是一个罕见的例外,而不是规则)。

    不过,你最好用 SQL 检索限制,即哪些用户适合(或不适合)哪些项目,并将它们输入启发式算法。

        2
  •  0
  •   Heiko Hatzfeld    15 年前

    这已经很长时间了,但我真的认为光标(我讨厌经常使用错误的光标)可以帮助这里。

    您可以考虑的另一件事是,用户实际上必须预订一天。这样,“建议用户”就可以在多个项目上模仿,因为还没有最后的结果。另外,我建议在一个项目中使用多个用户,这样分配用户的人就可以选择最有意义的内容。

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

    如果你有一个指定的使用,你的用例会变得更清晰。

        3
  •  0
  •   Philip Kelley    15 年前

    这包含了旅行推销员问题的阴影——如何在X个项目中最适合N个用户(尤其是如果您正在为每个项目寻找最佳/最合适的用户)。如果n和x值足够大,问题可能变得难以解决(也就是说,在你的有生之年你无法解决)。

    诚然,这是一个极端的情况。即便如此,当您试图向流程添加越来越多的功能时,我仍然可以看到需求不断膨胀。我的观点是,您试图解决的问题在T-SQL中可能无法合理地解决,更不用说单个查询了。为每个项目生成一个推荐用户列表,并让某人做最后的决定,在这里可能是明智的。