【问题标题】:Transpose Row to Column in SQL Server 2000在 SQL Server 2000 中将行转换为列
【发布时间】:2013-12-19 17:46:10
【问题描述】:

我正在尝试在 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

请帮助我如何获得预期的结果。 提前谢谢你。

【问题讨论】:

    标签: sql sql-server tsql sql-server-2000


    【解决方案1】:

    这里的谓词有几处错误:

    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];
    

    【讨论】:

      猜你喜欢
      • 2012-03-19
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 2013-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多