2013-06-12 75 views
1

这是我有:乘两个表先订购一个表,然后乘以

表1

CB/A/B/C 
X/5/2/1 
Y/2/3/0 

表2

CB/FL_X/FL_A/FL_V 
X/0.2/0.3/0.5 ---> (sum up to 1) 
Y/0/45/0.55/Null ---> (sum up to 1) 

现在我想乘这两个表得到:

表结果:

CB/FL/A/B/C 
X/X/0/0/0 
X/A/2/1/0 
X/V/3/1/1 
Y/X/1/2/0 
Y/A/1/1/0 

正如你可以看到表1中的数字和结果是整数。所以我必须使用“循环”功能。例如(CB(X,A)= FL_X(A)+ FL_A(A)+ FL_V(A) - > 5(从表1中可以看出) = 0 + 2 + 3(从表格结果)正如你可以看到FL_V(A)是0.5 * 5 = 2.5,如果我四舍五入它将是3.如果我对FL_A(A) - > 0.3 * 5 = 1.5〜2.3 + 2 = 5;因此虽然FL_X(A)为0.2 * 5 = 1,但结果应为0,因为总和应等于表1。第一。

这是一个更小的表比我的例子。

你能不能帮我写的SQL查询这个过程?

回答

0
  1. 将表2列'X/A/V'分为多行。你没有提到你使用的RDBMS。如果是SQL Server 2005+,这正是UNPIVOT所做的。这里有一个简单的例子,解释:UNPIVOT

  2. 现在只要与步骤1的结果加入表1(在CB柱)的事

所以部分答案(不四舍五入)看起来是这样的(假设的SQL Server):

SELECT 
    T3.CB, T3.FL, 
    T3.Ratio * T1.A, T3.Ratio * T1.B, T3.Ratio * T1.C 
FROM 
    (SELECT CB, FL_X, FL_A, FL_V FROM Table2) T2 
UNPIVOT 
    (Ratio FOR FL IN ([FL_X], [FL_A], [FL_V])) AS T3 
INNER JOIN Table1 T1 
    ON T1.CB = T3.CB 

在你的问题中最难的问题是确保新的数字正好相同的总和加起来为原有的。浮点运算非常棘手。你不能一致的ROUND或CEIL或FLOOR结果。例如:起始数字是1,比例是0.3/0.3/0.3。如果将所有数据舍入为零,则类似地,如果起始数字为2,则将所有值从0.6变为1,新和变为3.另一个例子是半数。如果从1开始,比率为0.5/0.5/0,则总和为0或2,具体取决于您是将中点向上还是向下移动。

解决方法是执行累计和以确保没有舍入错误。在你的情况下,有限的一组3个的值,它可以去是这样的:

SELECT 
    T1.CB, 
    -- Compute the decomposition of A into X/A/V. X_A + A_A + V_A should always be exactly A. 
    ROUND(T2.FL_X * T1.A) AS X_A, 
    ROUND((T2.FL_X + T2.FL_A) * T1.A) - ROUND(T2.FL_X * T1.A) AS A_A, 
    T1.A - ROUND((T2.FL_X + T2.FL_A) * T1.A) AS V_A 
    -- similarly for T1.B and T1.C 
FROM Table1 T1 
INNER JOIN Table2 T2 
    ON T1.CB = T2.CB 

现在,你只需要回答的两个部分结合(即unpivot的第二查询的结果)。