【发布时间】:2010-10-18 02:46:16
【问题描述】:
有没有办法在 SQL Server 2008 中对 PIVOTed 表执行更新,其中更改传播回源表,假设没有聚合?
【问题讨论】:
标签: sql sql-server sql-server-2008 pivot pivot-table
有没有办法在 SQL Server 2008 中对 PIVOTed 表执行更新,其中更改传播回源表,假设没有聚合?
【问题讨论】:
标签: sql sql-server sql-server-2008 pivot pivot-table
这只有在透视列形成唯一标识符时才真正起作用。那么让我们以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 字段,我如何知道我正在更新哪个星期日的时间?这仅在没有聚合的情况下才有效。我希望这会有所帮助!
【讨论】:
PIVOTs 始终需要在 pivot 子句中使用聚合函数。
因此总是存在聚合。
所以,不,它不能更新。
您可以根据声明在视图上放置INSTEAD OF TRIGGER,因此您可以使任何视图可更新。
例如here
【讨论】:
我不认为这是可能的,但是如果您发布有关您尝试解决的实际问题的具体信息,那么有人可能会就不同的处理方法给您一些建议。
【讨论】:
这只是一个猜测,但是你能把查询变成一个视图然后更新它吗?
【讨论】: