代码之家  ›  专栏  ›  技术社区  ›  Mitchel Sellers

SQL Server 2005以未知列数为轴心

  •  17
  • Mitchel Sellers  · 技术社区  · 16 年前

    我正在处理一组数据,这些数据如下所示。

    StudentName  | AssignmentName |  Grade
    ---------------------------------------
    StudentA     | Assignment 1   | 100
    StudentA     | Assignment 2   | 80
    StudentA     | Total          | 180
    StudentB     | Assignment 1   | 100
    StudentB     | Assignment 2   | 80
    StudentB     | Assignment 3   | 100
    StudentB     | Total          | 280
    

    作业的名称和数量是动态的,我需要得到以下结果。

    Student      | Assignment 1  | Assignment 2  | Assignment 3  | Total
    --------------------------------------------------------------------
    Student A    | 100           | 80            | null          | 180
    Student B    | 100           | 80            | 100           | 280
    

    我知道如何使用pivot来完成3个任务,只需简单地命名列,它正试图以一种动态的方式来完成,而我还没有找到一个好的解决方案。我正在尝试在SQLServer2005上执行此操作

    编辑

    理想情况下,我希望在不使用动态SQL的情况下实现它,因为这违反了策略。如果不可能…那么使用动态SQL的工作示例将起作用。

    7 回复  |  直到 16 年前
        1
  •  12
  •   Community CDub    8 年前

    我知道你说没有动力 SQL SQL .

    如果你能在我的网站上找到我对类似问题的答案 Pivot Table and Concatenate Columns PIVOT in sql 2005

    不存在易受注射伤害的情况,也没有很好的理由禁止注射。另一种可能性(如果数据很少更改)是执行代码生成,而不是动态生成 SQL 是定期生成到存储过程的。

        2
  •  9
  •   Taryn Frank Pearson    12 年前

    PIVOT

    CREATE TABLE yourtable
        ([StudentName] varchar(8), [AssignmentName] varchar(12), [Grade] int)
    ;
    
    INSERT INTO yourtable
        ([StudentName], [AssignmentName], [Grade])
    VALUES
        ('StudentA', 'Assignment 1', 100),
        ('StudentA', 'Assignment 2', 80),
        ('StudentA', 'Total', 180),
        ('StudentB', 'Assignment 1', 100),
        ('StudentB', 'Assignment 2', 80),
        ('StudentB', 'Assignment 3', 100),
        ('StudentB', 'Total', 280)
    ;
    

    动态轴:

    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT distinct ',' + QUOTENAME(AssignmentName) 
                        from yourtable
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = 'SELECT StudentName, ' + @cols + ' from 
                 (
                    select StudentName, AssignmentName, grade
                    from yourtable
                ) x
                pivot 
                (
                    min(grade)
                    for assignmentname in (' + @cols + ')
                ) p '
    
    execute(@query)
    

    看见 SQL Fiddle with Demo

    结果是:

    | STUDENTNAME | ASSIGNMENT 1 | ASSIGNMENT 2 | ASSIGNMENT 3 | TOTAL |
    --------------------------------------------------------------------
    |    StudentA |          100 |           80 |       (null) |   180 |
    |    StudentB |          100 |           80 |          100 |   280 |
    
        3
  •  1
  •   BoltBait    16 年前

        4
  •  0
  •   tsilb    16 年前

    您可以查询信息以获取列名和类型,然后在构建结果集时将结果用作子查询。注意,您可能需要稍微更改登录名的访问权限。

        6
  •  -1
  •   fancyPants    12 年前
    SELECT TrnType
    INTO #Temp1
    FROM
    (
        SELECT '[' + CAST(TransactionType AS VARCHAR(4)) + ']' AS TrnType FROM tblPaymentTransactionTypes
    ) AS tbl1
    
    SELECT * FROM #Temp1
    
    SELECT * FROM
    (
        SELECT FirstName + ' ' + LastName AS Patient, TransactionType, ISNULL(PostedAmount, 0) AS PostedAmount
        FROM tblPaymentTransactions
                INNER JOIN emr_PatientDetails ON tblPaymentTransactions.PracticeID = emr_PatientDetails.PracticeId
                INNER JOIN tblPaymentTransactionDetails ON emr_PatientDetails.PatientId = tblPaymentTransactionDetails.PatientID
                            AND tblPaymentTransactions.TransactionID = tblPaymentTransactionDetails.TransactionID
        WHERE emr_PatientDetails.PracticeID = 152
    ) tbl
    PIVOT (SUM(PostedAmount) FOR [TransactionType] IN (SELECT * FROM #Temp1)
    ) AS tbl4
    
        7
  •  -2
  •   Gabriele Petrioli    14 年前
    select studentname,[Assign1],[Assign2],[Assign3],[Total] 
    from 
    (
     select studentname, assignname, grade from student
    )s
    pivot(sum(Grade) for assignname IN([Assign1],[Assign2],[Assign3],[Total])) as pvt