如何在具有多个条件的特定列中执行计算

时间:2020-03-16 09:07:41

标签: sql sql-server loops

我正在寻找一种干净的解决方案,可以在几个条件下从单个列执行计算,并将其插入同一张表中。我现有的解决方案是使用带有许多变量声明的while循环,编写简单的查询来存储值,执行计算,最后将其作为新行插入到表中。但是,它看起来很杂乱且复杂。我想知道是否有更好的解决方案?

原始表

Week | Indicator | Value
  1        A         2
  1        B         3

  1        D         10
  1        E         5 

  1        X         12
  1        Y         6

  2        A         4
  2        B         5

  2        D         7
  2        E         3 

  2        X         4
  2        Y         2
 ...
 53

更新表

Week | Indicator | Value
  1        A         2
  1        B         3
  1        C         5

  1        D         10
  1        E         5
  1        F         5

  1        X         12
  1        Y         6
  1        Z         2

  2        A         4
  2        B         5
  2        C         9

  2        D         7
  2        E         3 
  2        F         4

  2        X         4
  2        Y         2
  2        Z         2

在此示例中,在更新的表中,每个第三行涉及同一周的不同计算,因此第三行为加法,第六行为减法,而第九行为除法。

该计算不仅限于加法,还可以包括其他形式的计算公式。我只是将加法用作一个简单的例子。

这是我的SQL解决方案的一个示例:

DECLARE @total_rows int;
SET @total_rows = (SELECT COUNT(*) FROM original_table);

DECLARE @wk varchar(5);
DECLARE @indicator1 char(1);
DECLARE @indicator2 char(1);
SET @indicator1 = 'A';
SET @indicator2 = 'B';

DECLARE @a_value int;
DECLARE @b_value int;
DECLARE @cal_value int;

DECLARE @iteration int
SET @iteration = 1

WHILE @iteration <= @total_rows
BEGIN

IF @iteration <= 53
    SET @wk = concat('W',@iteration)

SET  @a_value = (SELECT value 
FROM original_table
WHERE indicator = @indicator1 and week = @wk);

SET  @b_value = (SELECT value
FROM original_table
WHERE indicator = @indicator2 and week = @wk);

SET @cal_value =  (@a_value/ NULLIF(@b_value,0)) *1000000;
.... 

SET @iteration = @iteration + 1    
END

由于它很冗长,所以不会发布整个SQL脚本,但我希望您能理解它的要旨。

1 个答案:

答案 0 :(得分:0)

这不是像INSERTSUM那样简单吗?。

INSERT INTO dbo.YourTable ([Week],Indicator,[Value])
SELECT YT.[Week],
       'C' AS Indicator,
       SUM(YT.[Value]) AS [Value]
FROM dbo.YourTable YT
GROUP BY YT.[Week];

DB<>Fiddle