如何更新没有透视的表

时间:2017-12-07 08:24:14

标签: sql sql-server database

由于性能问题,我需要更好地更新表这是我当前的表结构现在基于weekNum,表2的值需要更新。目前使用pivot来获取更新,任何其他备用解决方案。请帮忙

表1:

╔════════╦══════╦════════╦═══════╗
║ Row ID ║ Desc ║ WeekNum║  Amt  ║
╠════════╬══════╬════════╬═══════╣
║      1 ║ Total║     01 ║ 25.00 ║
║      2 ║ Total║     02 ║ 55.00 ║
║      3 ║ Total║     04 ║ 78.00 ║
║      4 ║ Total║     06 ║ 99.00 ║
║      5 ║ Total║     07 ║ 54.00 ║
║      6 ║ Total║     09 ║ 58.00 ║
╚════════╩══════╩════════╩═══════╝

表2:

 ╔══╦═════╦══════╦══════╗═════╗═══════╗══════╗══════╗══════╗═════╗══════╗
 ║ID║ Desc║  01  ║  02  ║ 03  ║   04  ║  05  ║ 06   ║ 07   ║ 08  ║ 09   ║
 ╠══╬═════╬══════╬══════╣═════║═══════║══════║══════║══════║═════║═════ ║ 
 ║ 1║Total║25.00 ║55.00 ║NULL ║ 78.00 ║ NULL ║ 99.00║54.00 ║NULL ║58.00 ║
 ╚══╩═════╩══════╩══════╝═════╝═══════╝══════╝══════╝══════╝═════╝══════╝

1 个答案:

答案 0 :(得分:0)

如果PIVOT速度很慢,您可以将其分隔为9包含在事务中的不同更新。您的基本查询将是:

UPDATE Table1
SET [01] = T2.[Amnt]
FROM Table1 T1
INNER JOIN Table2 T2
    ON T1.[Desc] = T2.[Desc]
WHERE T2.[Week] = '01'; 

您将为每列执行此操作。如果您的真实示例包含更多不同的周数,则可以使用动态T-SQL语句来构建执行代码。它会更短,看起来更好。像这样:

DECLARE @DistitincWeeks TABLE
(
    [Week] VARCHAR(8)
);

INSERT INTO @DistitincWeeks ([Week])
SELECT DISTINCT [Week]
FROM Table1;

DECLARE @DynamictSQLStatement NVARCHAR(MAX)
       ,@CurrentWeek VARCHAR(8);

WHILE(EXISTS(SELECT 1 FROM @DistitincWeeks))
BEGIN;
    SELECT TOP (1) @CurrentWeek = [Week]
    FROM @DistitincWeeks;
    --

    SET @DynamictSQLStatement = @DynamictSQLStatement + 
    '
    UPDATE Table1
    SET [' + @CurrentWeek + '] = T2.[Amnt]
    FROM Table1 T1
    INNER JOIN Table2 T2
        ON T1.[Desc] = T2.[Desc]
    WHERE T2.[Week] = ''' +  @CurrentWeek  +''';    
    ';

    --
    DELETE FROM @DistitincWeeks
    WHERE [Week] @CurrentWeek 
END;

EXECUTE sp_executesql @DynamictSQLStatement;

或者,您可以在Table1上创建一个插入后触发器,在数据发生更改时修改Table2中的相应行。您可以使用上面代码的变体作为触发器主体。请确保您正在批量操作行,而不是循环或使用游标。

我不喜欢触发器,如果​​你有一个例行程序,存储过程或其他应用程序代码,我会建议你更新Table1数据,只需更新Table2中的数据。这对我来说更清楚,但你必须确保没有其他例程正在修改Table1中的数据。

Table2中的数据被修改为每X小时或每天执行大量更新时,最好不断更新小批量Table1

如果以下更新也很慢:

UPDATE Table1
SET [01] = T2.[Amnt]
FROM Table1 T1
INNER JOIN Table2 T2
    ON T1.[Desc] = T2.[Desc]
WHERE T2.[Week] = '01';

您应该检查表结构(列类型)本身和相应的索引。