2013-12-19 2 views
0

Я пытаюсь преобразовать строки в столбцы в SQL Server 2000. Хотя все строки были преобразованы в необходимые столбцы, но я не смог преобразовать значение в соответствующие столбцы.Переместить строку в колонку в SQL Server 2000

Мой код:

DROP TABLE prePivot1 
DROP TABLE results1 

CREATE TABLE prePivot1 (
    [StudentId] uniqueidentifier 
    , [Sub_Abbr] Varchar(100) 
    , [Total_marks] MONEY 
    ) 

CREATE TABLE results1 (
    [StudentId] uniqueidentifier 
    ) 

INSERT INTO prePivot1 
SELECT  '{4FD7CBBA-1621-4102-B4A3-000BF92E2F6E}', 'ENG', 55 
UNION SELECT '{4FD7CBBA-1621-4102-B4A3-000BF92E2F6E}', 'MBEN', 90 
UNION SELECT '{4FD7CBBA-1621-4102-B4A3-000BF92E2F6E}', 'ECO', 80 
UNION SELECT '{4FD7CBBA-1621-4102-B4A3-000BF92E2F6E}', 'PSc', 45 
UNION SELECT '{4FD7CBBA-1621-4102-B4A3-000BF92E2F6E}', 'PSY', 23 

UNION SELECT '{AD288712-5C97-446B-8AFE-003FC845B56B}', 'ENG', 90 
UNION SELECT '{AD288712-5C97-446B-8AFE-003FC845B56B}', 'ECO', 44 
UNION SELECT '{AD288712-5C97-446B-8AFE-003FC845B56B}', 'PSc', 45 
UNION SELECT '{AD288712-5C97-446B-8AFE-003FC845B56B}', 'BST', 23 
UNION SELECT '{AD288712-5C97-446B-8AFE-003FC845B56B}', 'ASS', 80 
UNION SELECT '{AD288712-5C97-446B-8AFE-003FC845B56B}', 'PSY', 93 




DECLARE @sql VARCHAR(8000) 
DECLARE @pivot varchar(10) 

DECLARE pivotCursor CURSOR LOCAL READ_ONLY FOR 
SELECT DISTINCT 
    [Sub_abbr] 
FROM 
    prePivot1 

OPEN pivotCursor 
    FETCH NEXT FROM pivotCursor INTO @pivot 

    WHILE (@@FETCH_STATUS = 0) BEGIN 

     SET @sql = ' 
     ALTER TABLE results1 ADD [' + CAST(@pivot AS VARCHAR(10)) + '] INT' 
     EXEC (@sql) 

     FETCH NEXT FROM pivotCursor INTO @pivot 
    END 
CLOSE pivotCursor 

INSERT INTO results1 ([studentId]) 
SELECT DISTINCT [StudentId] FROM prePivot1 

OPEN pivotCursor 
    FETCH NEXT FROM pivotCursor INTO @pivot 

    WHILE (@@FETCH_STATUS = 0) BEGIN 

     SET @sql = ' 
     UPDATE results1 
     SET 
      [' + CAST(@pivot AS VARCHAR(10)) + '] = pp.[total_marks] 
     FROM 
      prePivot1 pp 
     WHERE 
      pp.[total_marks] = ' + CAST(@pivot AS VARCHAR(10)) + ' 
      AND pp.[studentId] = results1.[studentId]' 

     EXEC (@sql) 

     FETCH NEXT FROM pivotCursor INTO @pivot 
    END 
CLOSE pivotCursor 
DEALLOCATE pivotCursor 

SELECT * FROM results1 

Пожалуйста, помогите мне, как это сделать, чтобы получить ожидаемый результат. Благодарим вас заранее.

ответ

0

Есть несколько вещей неправильно с предиката здесь:

pp.[total_marks] = ' + CAST(@pivot AS VARCHAR(10)) + ' 
  1. Вы фильтрование на неверном колонке
  2. Вы не генерируют правильную строку с @pivot части.

Это то, на что похоже, когда вы печатаете свою динамическую строку sql. Обратите внимание, что это приводит к соединению в столбце prePivot1.total_marks столбцу results1.ECO, который не является тем, что вы намереваетесь.

UPDATE 
    results1 
SET 
    [ECO] = pp.[total_marks] 
FROM 
    prePivot1 AS pp 
WHERE 
    pp.[total_marks] = ECO 
    AND pp.[studentId] = results1.[studentId] 

Исправленная версия (вы также не нужно привести переменную):

pp.[Sub_Abbr] = ''' + @pivot + ''' 

Лежащий решение немного меньше ошибок будет спараметрировать динамический SQL:

-- Change @sql --> nvarchar(4000)  
SET @sql = N' 
UPDATE 
    results1 
SET 
    ' + QUOTENAME(@pivot) + N' = pp.[total_marks] 
FROM 
    prePivot1 AS pp 
WHERE 
    pp.[Sub_Abbr] = @Sub_Abbr 
    AND pp.[studentId] = results1.[studentId];'; 

EXEC sp_executesql 
    @stmt = @sql, 
    @params = N'@Sub_Abbr varchar(10)', 
    @Sub_Abbr = @pivot; 

Это общий шаблон, который я использовал в sql2k для поворота только для справки: (я предполагаю, что StudentId, Sub_Abbr уникален, хотя схема явно не подтверждает это)

SELECT 
    [StudentId], 
    MAX(CASE WHEN [Sub_Abbr] = 'ASS' THEN [Total_marks] ELSE NULL END) AS [ASS], 
    MAX(CASE WHEN [Sub_Abbr] = 'BST' THEN [Total_marks] ELSE NULL END) AS [BST], 
    MAX(CASE WHEN [Sub_Abbr] = 'ECO' THEN [Total_marks] ELSE NULL END) AS [ECO], 
    MAX(CASE WHEN [Sub_Abbr] = 'ENG' THEN [Total_marks] ELSE NULL END) AS [ENG], 
    MAX(CASE WHEN [Sub_Abbr] = 'MBEN' THEN [Total_marks] ELSE NULL END) AS [MBEN], 
    MAX(CASE WHEN [Sub_Abbr] = 'PSc' THEN [Total_marks] ELSE NULL END) AS [PSc], 
    MAX(CASE WHEN [Sub_Abbr] = 'PSY' THEN [Total_marks] ELSE NULL END) AS [PSY] 
FROM 
    [dbo].[prePivot1] 
GROUP BY 
    [StudentId];