2011-11-07 53 views
3

我有一个SQL查询其选择与heighest重量小时的最佳组合,它使用递归CTE做找小时所有组合如下图所示SQL组合

Declare @EmpClasses table(Id int identity(1,1),ClassNum int,ClassWeight int,ClassHours int) 
Declare @HoursReq int; 

SET @HoursReq = 20; 


    INSERT INTO @EmpClasses VALUES(1001,10,10),(1002,9,5),(1003,8,4),(1004,7,3),(1005,6,2),(1006,5,2),(1007,4,1); 

    --INSERT INTO @EmpClasses VALUES(1001,2,2),(1002,2,2),(1003,2,2),(1004,2,2),(1005,2,2),(1006,2,2),(1007,2,2),(1008,2,2),(1009,2,2),(1010,2,2); 
    --INSERT INTO @EmpClasses VALUES(1011,2,2),(1012,2,2),(1013,2,2),(1014,2,2),(1015,2,2),(1016,2,2),(1017,2,2),(1018,2,2),(1019,2,2),(1020,2,2); 
    --INSERT INTO @EmpClasses VALUES(1021,2,2),(1022,2,2),(1023,2,2),(1024,2,2),(1025,2,2),(1026,2,2),(1027,2,2),(1028,2,2),(1029,2,2),(1030,2,2); 


    WITH cte (Id,comIds,Total,TotalWeight) 
    AS 
    (
    SELECT Id 
      ,Cast(ClassNum as varchar(max)) + ',' 
      ,ClassHours 
      ,ClassWeight 
    FROM @EmpClasses 
    UNION ALL 
    SELECT ec.Id 
      ,cte.comIds + Cast(ec.ClassNum as varchar(max)) + ',' 
      ,cte.Total + ec.ClassHours 
      ,cte.TotalWeight + ec.ClassWeight 
    FROM @EmpClasses AS ec JOIN cte ON ec.Id < cte.Id 
    ) 
    SELECT top(1)comids,Total,TotalWeight 
    FROM cte 
    Where Total = @HoursReq 
    order by TotalWeight desc 

然而,问题在于,当行数增加以迭代时。这需要很长时间。 注: - 请取消注释上面几行来检查问题

任何有关这将是极大的帮助表示赞赏

+0

[本系列文章可能有助于]您可以验证(http://sqlblog.com/blogs/hugo_kornelis/archive /2011/11/01/bin-packing-part-6-further-improvements.aspx) –

回答

1

cte产生的行数是2^n-1其中n是在@EmpClasses表中的记录数。

因此,如果您只使用7条记录,则会生成127条记录。

但是,如果您使用37条记录,如完整示例中所示,它需要生成137.438.953.471行。这需要一些时间,即使你有一个快速的服务器。

如果在CTE的底部更改选择,用一个简单的

select * from cte 
+0

感谢Sweko对此进行调查。 我只是检查是否有更好的方法来做到这一点,因为我只需要选择体重最高的小时的最佳组合。 – user1033677