Есть ли способ выполнить обновления в таблице PIVOTed в SQL Server 2008, где изменения распространяются обратно в исходную таблицу, если нет агрегации?Обновления на PIVOT в SQL Server 2008
ответ
Это будет только действительно работать, если повернуты столбцы образуют уникальный идентификатор. Итак, возьмем пример Багги; вот исходная таблица:
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
имеет обновленную версию часов для задачи, которая имела место на 11/16/1980, и мы хотим сохранить, что вернуться к исходному таблица, поэтому мы используем 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
Вы заметите, что я изменил пример Багги, чтобы удалить агрегацию на день-неделю. Это потому, что нет возврата и обновления, если вы выполняете какие-либо агрегации. Если я обновляю поле SUNHours, как узнать, какие воскресные часы я обновляю? Это будет работать, только если нет агрегации. Надеюсь, это поможет!
Это всего лишь догадка, но можете ли вы сделать запрос в виде, а затем обновить его?
Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. –
@ElVieejo, спасибо за комментарий cut-n-paste. Однако я не согласен с вами в анализе моего ответа. –
добро пожаловать. Вы спрашиваете, а не спрашиваете :) –
Я не считаю, что это возможно, но если вы публикуете информацию о реальной проблеме, которую пытаетесь решить, кто-то может дать вам несколько советов по другому подходу к ее обработке.
PIVOT
s всегда требует агрегатной функции в пункте поворота.
Таким образом, всегда существует агрегация.
Таким образом, нет, он не может быть обновляемым.
Вы можете нанести INSTEAD OF TRIGGER
на представление, основанное на инструкции, и, таким образом, вы можете сделать любой вид обновляемым.
Пример here
Как я могу использовать триггер INSTEAD OF для обновления исходной таблицы? – brian
Пример здесь: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=120679 –
Awesome @brian. Большое спасибо за объяснение. – 2017-02-20 20:09:40