SQL Server 2008 中 PIVOT 的更新
如果没有聚合,有没有办法在 SQL Server 2008 中对 PIVOTed 表执行更新,其中更改传播回源表?
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?
推荐答案
这只有在透视列形成唯一标识符时才真正起作用.那么让我们以Buggy的例子为例;这是原始表格:
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)
那么你在 ##Pivoted
中有你的透视表.现在您对小时字段之一执行更新:
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
现在 ##Pivoted
有一个更新版本的小时数,该任务发生在 1980 年 11 月 16 日,我们希望将其保存回原始表,因此我们使用 UNPIVOT
:
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
您会注意到我修改了 Buggy 的示例以删除按星期几的聚合.那是因为如果您执行任何类型的聚合,就没有回头路和更新.如果我更新 SUNHours 字段,我如何知道我正在更新哪个星期日的时间?这仅在没有聚合的情况下才有效.我希望这会有所帮助!
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!
相关文章