1

我一直在研究这个,还没有找到可用的答案。我是 SQL Server 的中度黑客,并且在函数和存储过程中使用参数方面取得了一些成功,但这是我似乎无法理解的组合。

为了清楚起见,我总结了以下情景:我的公司将计算机作为笔记本电脑、台式机和配件进行销售。我有一个 tbl_Computers,我在其中维护 Computer_Type、Model_Num 和 Mix_Percent,如下所示:

Desktop  ABC  .75  
Desktop  XYZ  .25  
Laptop   DEF  .60  
Laptop   MNO  .40

我们还有一个按月预测的表格,我在其中维护 Computer_Type、Jul_Num、Aug_Num 和 Sep_Num,如下所示:

Desktop  100  200  150  
Laptop   300  400  700

我为计划物料清单创建了一个功能,该功能将查找给定型号在过去 12 个月内销售的所有组件和配件。它的工作原理如下:
P_BOM ("ABC") 将生成一个包含两列的表:Component 和 Comp_Percent

CPU        1  (This means we sell 1 CPU with every desktop)  
Hard Drive 2  (We sell 2 with every desktop)  
Printer    .8 (80% of the time we sell a printer)

我希望我的存储过程做的是提供一个看起来像这样的单个组合表,其中包含以下标题 Component、Jul_Num、Aug_Num 和 Sep_Num:

CPU         400  600  850  
Hard Drive  500  800  1000

我通过总结以下逻辑得到 CPU 编号:
Desktop's Jul_Num x ABC's Mix_Percentage x ABC's CPU Comp_Percent
Desktop's Jul_Num x XYZ's Mix_Percentage x XYZ's CPU Comp_Percent
Laptop's Jul_Num x ABC's Mix_Percentage x ABC's CPU Comp_Percent
Laptop's Jul_Num x XYZ's Mix_Percentage x XYZ's CPU Comp_Percent
40 100 x .75 x 1) + (100 x .25 x 1) + (300 x .6 x 1) + (300 x .4 x 1)

有任何想法吗?

谢谢,
罗伯

编辑:

感谢建议这不必是一个迭代问题,而是一个基于表格的解决方案。

我创建了第一个表给我:

ABC CPU          3  3   1
ABC Hard Drive   6  3   2
DEF CPU          2  2   1
DEF Hard Drive   2  2   1
MNO CPU          1  1   1
MNO Hard Drive   1  1   1
XYZ CPU          1  1   1
XYZ Hard Drive   2  1   2

这是 SQL:

SELECT        All_Components.Model_Num, All_Components.Part_Num, SUM(All_Components.Qty) AS Total, TTO.Target_Total, SUM(All_Components.Qty) 
                     / TTO.Target_Total AS Comp_Percent
FROM            (SELECT        Test_tbl_Computers.Model_Num, Test_tbl_Orders_2.Order_Num, Test_tbl_Orders_2.Part_Num, Test_tbl_Orders_2.Qty
                      FROM            Test_tbl_Orders AS Test_tbl_Orders_2 CROSS JOIN
                                                Test_tbl_Computers) AS All_Components INNER JOIN
                         (SELECT        Test_tbl_Orders.Part_Num, SUM(Test_tbl_Orders.Qty) AS Target_Total
                           FROM            Test_tbl_Orders INNER JOIN
                                                     Test_tbl_Computers AS Test_tbl_Computers_1 ON Test_tbl_Orders.Part_Num = Test_tbl_Computers_1.Model_Num
                           GROUP BY Test_tbl_Orders.Part_Num) AS TTO ON All_Components.Model_Num = TTO.Part_Num
WHERE        (All_Components.Order_Num IN
                         (SELECT        Order_Num
                           FROM            Test_tbl_Orders AS Test_tbl_Orders_1
                           WHERE        (Part_Num = All_Components.Model_Num))) AND (All_Components.Part_Num <> All_Components.Model_Num)

然后,为了防止它成为我无法驯服的 SQL 怪物,我创建了另一个函数来对预测和混合百分比进行内部连接,然后将所有按 Part_Num 分组的数字相加。

如果不出意外,我很感激必须写下我的问题以帮助集中我的想法。

4

2 回答 2

1

“Computer_Type、Jul_Num、Aug_Num 和 Sep_Num”

每月一列适用于报告或数据输入界面,但如果您真的以这种方式存储数据,您将绝对让自己发疯。如果您有办法返回并将该表更改为“Computer_Type,Year,Month,Num”或“Computer_Type,Date,Num”,那么您应该这样做。

于 2013-07-03T16:34:27.580 回答
0

我不明白你为什么在这里需要一个函数。您在此处说明的所有数据都可以存储在表中,然后通过简单的连接获取。即使 BOM 是递归的,您也可以使用 CTE。

如果您坚持使用该函数,您可以使用CROSS APPLY该函数对每一行调用该函数。


到目前为止,我创建的唯一功能是创建一个包含两列的表格,其中包含在与特定桌面模型相同的销售订单上销售的所有组件。您是否建议我将该表的结果发布到另一个表并继续为函数的每个实例插入新行?

我明白了,你不需要使用函数。有很多不同的可能性,

您可能非常接近它的一个是将函数转换为 SP 并使用

INSERT INTO [TableName]
EXEC [SP_NAME]

另一个将查询转换为累积子查询或 CTE(见下文)并将其与其他查询连接。

一般来说,尽量避免每次都创建函数,因为它们会对数据库造成很大的损害。

BOM 不是递归的。我对CTE不熟悉。

当您有许多串联的子查询时,公用表表达式 (CTE) 是很好的工具,一旦您习惯了它们,它们就会为复杂的查询带来很多清晰度 (IMO)。CTE 还为递归提供本机支持。网上有很多文章可以指导你。只是谷歌 CTE 示例或 CTE 教程

我没有 CROSS APPLY 的经验。

交叉申请:从页面http://technet.microsoft.com/en-us/library/ms175156(v=sql.105).aspx

APPLY 运算符允许您为查询的外部表表达式返回的每一行调用表值函数。

最后也是最重要的

任何例子将不胜感激

如果你能给我你已经拥有的部分脚本,我会尝试将它转换为我打算指导你的查询。

于 2013-07-03T16:40:31.007 回答