2009-04-07 3 views

ответ

1

Это будет только действительно работать, если повернуты столбцы образуют уникальный идентификатор. Итак, возьмем пример Багги; вот исходная таблица:

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, как узнать, какие воскресные часы я обновляю? Это будет работать, только если нет агрегации. Надеюсь, это поможет!

+0

Awesome @brian. Большое спасибо за объяснение. – 2017-02-20 20:09:40

0

Это всего лишь догадка, но можете ли вы сделать запрос в виде, а затем обновить его?

+0

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. –

+0

@ElVieejo, спасибо за комментарий cut-n-paste. Однако я не согласен с вами в анализе моего ответа. –

+0

добро пожаловать. Вы спрашиваете, а не спрашиваете :) –

0

Я не считаю, что это возможно, но если вы публикуете информацию о реальной проблеме, которую пытаетесь решить, кто-то может дать вам несколько советов по другому подходу к ее обработке.

1

PIVOT s всегда требует агрегатной функции в пункте поворота.

Таким образом, всегда существует агрегация.

Таким образом, нет, он не может быть обновляемым.

Вы можете нанести INSTEAD OF TRIGGER на представление, основанное на инструкции, и, таким образом, вы можете сделать любой вид обновляемым.

Пример here

+0

Как я могу использовать триггер INSTEAD OF для обновления исходной таблицы? – brian

+0

Пример здесь: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=120679 –