Updates on PIVOTs in SQL Server 2008

后端 未结 4 1979
误落风尘
误落风尘 2021-01-07 10:11

Is there a way to perform updates on a PIVOTed table in SQL Server 2008 where the changes propagate back to the source table, assuming there is no aggregation?

相关标签:
4条回答
  • 2021-01-07 10:20

    PIVOTs always require an aggregate function in the pivot clause.

    Thus there is always aggregation.

    So, no, it cannot be updatable.

    You CAN put an INSTEAD OF TRIGGER on a view based on the statement and thus you can make any view updatable.

    Example here

    0 讨论(0)
  • 2021-01-07 10:39

    This will only really work if the pivoted columns form a unique identifier. So let's take Buggy's example; here is the original table:

    TaskID    Date    Hours
    

    and we want to pivot it into a table that looks like this:

    TaskID    11/15/1980    11/16/1980    11/17/1980 ... etc.
    

    In order to create the pivot, you would do something like this:

    DECLARE @FieldList NVARCHAR(MAX)
    
    SELECT
        @FieldList =
        CASE WHEN @FieldList <> '' THEN 
            @FieldList + ', [' + [Date] + ']' 
        ELSE 
            '[' + [Date] + ']' 
        END
    FROM
        Tasks
    
    
    
    DECLARE @PivotSQL NVARCHAR(MAX)
    SET @PivotSQL = 
        '
            SELECT 
                TaskID
                , ' + @FieldList + '
            INTO
                ##Pivoted
            FROM 
                (
                    SELECT * FROM Tasks
                ) AS T
            PIVOT
                (
                    MAX(Hours) FOR T.[Date] IN (' + @FieldList + ') 
                ) AS PVT
        '
    
    EXEC(@PivotSQL)
    

    So then you have your pivoted table in ##Pivoted. Now you perform an update to one of the hours fields:

    UPDATE
        ##Pivoted
    SET
        [11/16/1980 00:00:00] = 10
    WHERE
        TaskID = 1234
    

    Now ##Pivoted has an updated version of the hours for a task that took place on 11/16/1980 and we want to save that back to the original table, so we use an UNPIVOT:

    DECLARE @UnPivotSQL NVarChar(MAX)
    SET @UnPivotSQL = 
        '
            SELECT
                  TaskID
                , [Date]
                , [Hours]
            INTO 
                ##UnPivoted
            FROM
                ##Pivoted
            UNPIVOT
            (
                Value FOR [Date] IN (' + @FieldList + ')
            ) AS UP
    
        '
    
    EXEC(@UnPivotSQL)
    
    UPDATE
        Tasks
    SET
        [Hours] = UP.[Hours]
    FROM
        Tasks T
    INNER JOIN
        ##UnPivoted UP
    ON
        T.TaskID = UP.TaskID
    

    You'll notice that I modified Buggy's example to remove aggregation by day-of-week. That's because there's no going back and updating if you perform any sort of aggregation. If I update the SUNHours field, how do I know which Sunday's hours I'm updating? This will only work if there is no aggregation. I hope this helps!

    0 讨论(0)
  • 2021-01-07 10:40

    this is just a guess, but can you make the query into a view and then update it?

    0 讨论(0)
  • 2021-01-07 10:41

    I don't believe that it is possible, but if you post specifics about the actual problem that you're trying to solve someone might be able to give you some advice on a different approach to handling it.

    0 讨论(0)
提交回复
热议问题