我有2个表,我正在尝试用它来执行一些计算。我的第一个(基本上是'ABC'并且不包括NONE的功能集)表看起来像这样:
TABLE: test3
rowID v1 v2 v3 combo initialValue
1 NULL NULL M170_4 C NULL
2 NULL M170_3 NULL B NULL
3 NULL M170_3 M170_4 BC NULL
4 M170_2 NULL NULL A NULL
5 M170_2 NULL M170_4 AC NULL
6 M170_2 M170_3 NULL AB NULL
7 M170_2 M170_3 M170_4 ABC NULL
我需要更新每一行的initialValue
列。
我有另一张这样的表:
TABLE: my_data_db
ID WEIGHT v1 v2 v3
1 1.34 0.10 NULL NULL
2 0.53 0.75 NULL 0.75
3 1.24 0.25 0.10 0.25
4 0.95 NULL 1.00 0.10
5 0.72 0.75 NULL 0.10
6 0.145 1.00 1.00 0.75
...
AND SO ON
对于test3
中的每一行,我需要计算my_data_db
中相应行的乘积之和,如下所示:
DECLARE @total FLOAT
SET @total = 4898.947426
UPDATE test3 SET initialValue =
(
SELECT SUM(v3 * WEIGHT / @total) FROM my_data_db
)
WHERE combo = 'C'
UPDATE test3 SET initialValue =
(
SELECT SUM(v2 * WEIGHT / @total) FROM my_data_db
)
WHERE combo = 'B'
UPDATE test3 SET initialValue =
(
SELECT SUM(v2 * v3 * WEIGHT / @total) FROM my_data_db
)
WHERE combo = 'BC'
UPDATE test3 SET initialValue =
(
SELECT SUM(v1 * WEIGHT / @total) FROM my_data_db
)
WHERE combo = 'A'
UPDATE test3 SET initialValue =
(
SELECT SUM(v1 * v2 * WEIGHT / @total) FROM my_data_db
)
WHERE combo = 'AB'
UPDATE test3 SET initialValue =
(
SELECT SUM(v1 * v3 * WEIGHT / @total) FROM my_data_db
)
WHERE combo = 'AC'
UPDATE test3 SET initialValue =
(
SELECT SUM(v1 * v2 * v3 * WEIGHT / @total) FROM my_data_db
)
WHERE combo = 'ABC'
我无法弄清楚如何简化我的UPDATE
,所以我不必每行更新一次。我上面的UPDATE
代码虽然丑陋但并不算太多,但真正的问题是我会有类似于test3
的表格,这些表格有超过一百万行,所有表格都有其独特的组合各栏目。另外,如果没有必要,我不想使用CURSOR
或WHILE
循环。使用CURSOR
的解决方案(参见下面提到的上一篇文章)在我的电源设置表变大时无法扩展。
感谢。
(注意:以下是:Avoiding cursors to update many records using a trigger)
答案 0 :(得分:1)
以下是与您的一系列更新相同的计算,但使用单个语句。您可以看到此处未使用combo
列。而是为两个表中的每一个生成一组新的列。新列在参与表和计算时都参与其中。
;
WITH
test3_with_keys AS (
SELECT
RowID,
key1 = CASE WHEN v1 IS NULL THEN 0 ELSE 1 END,
key2 = CASE WHEN v2 IS NULL THEN 0 ELSE 1 END,
key3 = CASE WHEN v3 IS NULL THEN 0 ELSE 1 END
FROM @test3
),
my_data_db_with_keys AS (
SELECT
WEIGHT,
v1,
v2,
v3,
key1 = CASE WHEN v1 IS NULL THEN 0 ELSE 1 END,
key2 = CASE WHEN v2 IS NULL THEN 0 ELSE 1 END,
key3 = CASE WHEN v3 IS NULL THEN 0 ELSE 1 END
FROM @my_data_db
),
calculated AS (
SELECT
t.RowID,
initialValue = SUM(
ISNULL(NULLIF(t.key1, 0) * d.v1, 1) *
ISNULL(NULLIF(t.key2, 0) * d.v2, 1) *
ISNULL(NULLIF(t.key3, 0) * d.v3, 1) *
d.WEIGHT / @total
)
FROM test3_with_keys t
INNER JOIN my_data_db_with_keys d ON t.key1 <= d.key1
AND t.key2 <= d.key2
AND t.key3 <= d.key3
GROUP BY
t.rowID
)
UPDATE test3
SET initialValue = c.initialValue
FROM calculated c
WHERE test3.RowID = c.RowID;
注意:假设RowID
值是唯一的。