【问题标题】:Updates on PIVOTs in SQL Server 2008SQL Server 2008 中 PIVOT 的更新
【发布时间】:2010-10-18 02:46:16
【问题描述】:

有没有办法在 SQL Server 2008 中对 PIVOTed 表执行更新,其中更改传播回源表,假设没有聚合?

【问题讨论】:

    标签: sql sql-server sql-server-2008 pivot pivot-table


    【解决方案1】:

    这只有在透视列形成唯一标识符时才真正起作用。那么让我们以Buggy的例子为例;这是原始表格:

    TaskID    Date    Hours
    

    我们想把它转成一个如下所示的表格:

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

    为了创建枢轴,您可以执行以下操作:

    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)
    

    那么你在##Pivoted 中有你的透视表。现在您对小时字段之一执行更新:

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

    现在##Pivoted 有一个在 1980 年 11 月 16 日发生的任务的小时更新版本,我们希望将其保存回原始表,因此我们使用 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
    

    您会注意到我修改了 Buggy 的示例以删除按星期几的聚合。那是因为如果您执行任何类型的聚合,就没有回头路和更新。如果我更新 SUNHours 字段,我如何知道我正在更新哪个星期日的时间?这仅在没有聚合的情况下才有效。我希望这会有所帮助!

    【讨论】:

    • 真棒@brian。非常感谢您的解释。
    【解决方案2】:

    PIVOTs 始终需要在 pivot 子句中使用聚合函数。

    因此总是存在聚合。

    所以,不,它不能更新。

    您可以根据声明在视图上放置INSTEAD OF TRIGGER,因此您可以使任何视图可更新。

    例如here

    【讨论】:

    • 如何使用 INSTEAD OF 触发器更新原始表?
    【解决方案3】:

    我不认为这是可能的,但是如果您发布有关您尝试解决的实际问题的具体信息,那么有人可能会就不同的处理方法给您一些建议。

    【讨论】:

      【解决方案4】:

      这只是一个猜测,但是你能把查询变成一个视图然后更新它吗?

      【讨论】:

      • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
      • @ElVieejo,感谢您的剪切粘贴评论。但是,我不同意你对我的回答的分析。
      • @ElVieejo,OP 没有提供有关其表格的任何详细信息。在某些情况下,您可以对视图发出 UPDATE(这取决于未提供的详细信息)。如果我有足够的表格信息并且可行,我会提供一个工作示例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多