通过先排序一个表然后相乘来乘以两个表

时间:2013-06-12 18:27:27

标签: sql integer multiplying

这就是我所拥有的:

表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的总和应与表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.这是通过排序表2来完成的首先是价值观。

这是一个比我小得多的桌子的例子。

你能帮我写一下这个过程的SQL查询吗?

1 个答案:

答案 0 :(得分:0)

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

  2. 现在只需将表1加入第1步的结果(在CB专栏上)

  3. 所以部分答案(没有舍入)看起来像这样(假设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。如果你将所有内容都向下舍入,则总和变为0.同样,如果起始数为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
    

    现在你只需要结合答案的两个部分(即取消第二个查询的结果)。