這絕對可以在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