这绝对可以在SQL中完成,但优化它以适用于大集合将是挑战。下面是一个解决方案,它使用公共表格表计算目标零件编号的可能排列组合,将这些排列组合到它们的数量总和中,并选择SUM与目标匹配的第一个排列组合。
该排列,然后用来识别SerialNumbers从数据集选择:
declare @partNum char(4)
SET @partNum = '0001'
declare @quantity int
SET @quantity = 40
declare @data TABLE (
SerialNumber int identity(1,1),
PartNumber char(4),
Quantity int
);
INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 20);
INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 10);
INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 20);
INSERT INTO @data (PartNumber, Quantity) VALUES ('0002', 20);
INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 20);
WITH
cte_items as (
select * from @data where PartNumber = @partNum
),
cte_perms as (
select cast(cast(SerialNumber as binary(4)) as varbinary(max)) as perm, 1 as numentries
from cte_items
union all
select cast(n.SerialNumber as binary(4)) + p.perm, p.numentries + 1
from cte_perms p
join cte_items n on n.SerialNumber < cast(substring(perm,1,4) as int)
),
cte_permlist as (
select row_number() over (order by (select 1)) as permnum, perm
from cte_perms
)
SELECT d1.SerialNumber, d1.PartNumber, d1.Quantity
FROM @data d1
INNER JOIN (
SELECT
cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) as SerialNumber
from cte_permlist p
join @data n on n.SerialNumber = n.SerialNumber
where cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) != 0
and p.permnum = (
SELECT TOP 1 permutations.permnum
FROM @data d2
CROSS APPLY (
SELECT
p.permnum,
cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) as SerialNumber
from cte_permlist p
join @data n on n.SerialNumber = n.SerialNumber
where cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) != 0
) permutations
WHERE PartNumber = @partNum
and permutations.SerialNumber = d2.SerialNumber
GROUP BY permutations.permnum
HAVING SUM(d2.Quantity) = @quantity
ORDER BY permnum desc
)
) pSn on pSn.SerialNumber = d1.SerialNumber
结果:
SerialNumber PartNumber Quantity
------------ ---------- -----------
1 0001 20
3 0001 20
一旦查询优化器获取与此做了它应该是相当有效率除非对于目标零件编号,有不止一个排列组合。
我是否正确地将您所需的查询汇总为'返回满足给定零件编号的数量要求的一组行'?当然,可能有0个或多个候选集。这看起来并不是很友好 - 这种逻辑很可能在不同的编程语言中得到更好的处理。 – 2011-05-24 22:46:05
是指一个或多个记录的数量总和为40的位置? – 2011-05-24 22:49:31
是的,它是一个艰难的.. – BizApps 2011-05-24 23:13:02