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的总和应该与表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查询吗?

4

1 回答 1

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。如果将所有内容四舍五入,则总和变为 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

现在您只需将答案的两个部分结合起来(即取消透视第二个查询的结果)。

于 2013-06-12T20:06:05.400 回答