这里的任务是定义从供应商处订购物品(零件)的最佳(如下详述)方式。
表模式的相关部分(带有一些示例数据)是
项目
ID NUMBER
1 Item0001
2 Item0002
3 Item0003
供应商
ID NAME DELIVERY DISCOUNT
1 Supplier0001 0 0
2 Supplier0002 0 0.025
3 Supplier0003 20 0
DELIVERY
是该供应商对每次交货征收的运费(以美元计)。是供应商准时付款所允许DISCOUNT
的结算折扣(百分比,即上述的 2.5% )。ID=2
供应商物品
SUPPLIER_ID ITEM_ID PRICE
1 2 21.67
1 5 45.54
1 7 32.97
这是供应商和项目之间的多对多连接,供应商为该项目收取的价格(以美元为单位)。每个项目至少有 1 个供应商,但有些有多个。供应商可能没有项目。
零件请求
ID ITEM_ID QUANTITY LOCATION_ID ORDER_ID
1 59 4 2 (null)
2 89 5 2 (null)
3 42 4 2 (null)
此表是来自现场站点的请求,要求供应商订购和交付到该站点的零件。将任意数量的物品运送到站点会产生运送费用。订购零件时,会将其ORDER_ID
插入表中,因此我们只关心那些ORDER_ID IS NULL
问题是,为每个“位置”订购这些部件的最佳方式是什么,其中需要向用户提供 3 个最佳解决方案以供选择。
- 供应商数量最少的订单组合
- 总成本最低的订单组合,即
QUANTITY*PRICE
每个项目的总和加上DELIVERY
每个订单的总和,忽略所有订单DISCOUNT
- 作为第 2 项,但考虑到
DISCOUNT
显然,我需要确定可用的订单组合,然后确定最佳的订单组合变得微不足道,但我有点停留在处理构建组合的有效方法上。
我在 SQL Server 2008 中使用随机数据构建了一些 SQL 小提琴。这个有 100 个项目,10 个供应商和 100 个请求。这个有 1000 个项目,50 个供应商和 250 个请求。表架构是相同的。
更新
我推断该解决方案必须是递归的,并且我构建了一个很好的表值函数来获取,但我遇到了 SQL Server 中递归的 32 个硬限制。无论如何,我对它感到不舒服,因为它暗示了比 RDMS 更多的程序语言解决方案。
所以我现在正在玩 CTE 递归。
根查询是:
SELECT DISTINCT
'' SOLUTION_ID
,LOCATION_ID
,SUPPLIER_ID
,(subquery I haven't quite worked out) SOLE_SUPPLIER
FROM PartsRequests pr
INNER JOIN
SupplierItems si ON pr.ITEM_ID=si.ITEM_ID
WHERE pr.ORDER_ID IS NULL
这获得了所有可以提供所需物品的供应商,并且肯定是一种解决方案,可能不是最佳的。如果供应商是该位置所需任何产品的唯一供应商,则子查询设置一个标志;如果是这样,它们必须是任何解决方案的一部分。
递归部分是通过 CTE.SUPPLIER_ID<>CTE.SUPPLIER_ID 的方式将供应商一一移除,如果仍然覆盖所有项目,则添加它们。SOLUTION_ID 将是已删除供应商的 CSV 列表,部分用于唯一标识每个解决方案,部分用于检查,因此我得到组合而不是排列。
仍在研究细节,此更新的目的是让社区说“是的,看起来那会起作用”,或者“你这个白痴,那不会起作用,因为......”
谢谢