zoukankan      html  css  js  c++  java
  • SQL SERVER行转换列及PIVOT

    --*****************SQL 行转列***************************
    --创建实例表
    IF OBJECT_ID('TB')IS NOT NULL
     DROP TABLE TB
    GO
    --构建实例数据
    CREATE TABLE TB(姓名 NVARCHAR(10),课程 NVARCHAR(10),分数 INT)

    INSERT INTO TB VALUES(N'张三',N'语文',74)

    INSERT INTO TB VALUES(N'张三',N'数学',83)

    INSERT INTO TB VALUES(N'张三',N'物理',93)

    INSERT INTO TB VALUES(N'李四',N'语文',74)

    INSERT INTO TB VALUES(N'李四',N'数学',84)

    INSERT INTO TB VALUES(N'李四',N'物理',94)

    SELECT * FROM TB WITH(NOLOCK)
    GO
    --***************行转列***************************
    --实现课程列值旋转为列名
        --使用SQL SERVER 2000静态SQL
         SELECT 
             姓名
            ,MAX(CASE 课程 
                 WHEN N'语文'  THEN 分数 
                 ELSE 0 
             ENDAS N'语文' 
            ,MAX(CASE 课程 
                 WHEN N'数学'  THEN 分数 
                 ELSE 0 
             ENDAS N'数学' 
            ,MAX(CASE 课程 
                 WHEN N'物理'  THEN 分数 
                 ELSE 0 
             ENDAS N'物理'  
         FROM TB 
         GROUP BY 姓名
        --SQL SERVER 2000动态SQL,指课程不止语文、数学、物理这三门课程。
        --变量按SQL语言顺序赋值
        DECLARE @SQL1 NVARCHAR(MAX)

        SET @SQL1=N'SELECT 姓名'

        SELECT 
            @SQL1=@SQL1+N',MAX(CASE 课程 
                WHEN N
    '''+课程+N''' THEN 分数 
                ELSE 0 
            END)[
    '+课程+']'  
        FROM
                SELECT 
                    DISTINCT 课程 
                FROM TB 
             )A  
        SET @SQL1=@SQL1+N' FROM TB GROUP BY 姓名'

        EXEC(@SQL1)
        --使用ISNULL(),变量先确定动态部分
        DECLARE @SQL NVARCHAR(MAX)
        SELECT 
            @SQL=ISNULL(@SQL+',',''+N' MAX(CASE 课程 
                    WHEN N
    '''+课程+ N''' THEN 分数 
                    ELSE 0 
                END) [
    '+课程+N']'  
        FROM(
                SELECT 
                    DISTINCT 课程 
                FROM TB
             )AS A      
        SET @SQL=N'SELECT 
                       姓名,
    '+@SQL+N' FROM TB GROUP BY 姓名'

        EXEC(@SQL)

        PIVOT--列值转换为列名,即行转列

        PIVOT(聚合函数(列) FOR 列 in (…) )AS P
        完整语法:
        Table_Source
        PIVOT
        (
        聚合函数【MAX,SUM,等】(value_column)
        FOR pivot_column【要成为列标题的值的列】
           IN(列值 of pivot_column)
        ) 别命
        --使用SQL SERVER 2005静态SQL
     SELECT 
         姓名
        ,语文
        ,数学
        ,物理 
     FROM TB 
     PIVOT
     ( 
          MAX(分数)FOR 课程 IN 
         ( 
              语文 
             ,数学 
             ,物理 
         ) 
     )A  
        --使用SQL Server 2005动态SQL
     --1使用STUFF( character_expression , start , length ,character_expression ),start 从索引1开始
        DECLARE @SQL2 NVARCHAR(MAX)
        SET  @SQL2=''  
        SELECT  @SQL2= @SQL2+','+课程 FROM TB GROUP BY 课程 
        PRINT @SQL2
        SET @SQL2=STUFF@SQL2,1,1,'')--去掉首个','
        PRINT @SQL2
        SET @SQL2=N'SELECT * FROM TB PIVOT (MAX(分数) FOR 课程 IN ('+ @SQL2+'))A'
        EXEC@SQL2)

        --2使用ISNULL()
        DECLARE  @SQL3 NVARCHAR(MAX)
        SELECT  @SQL3=ISNULL@SQL3+',','')+课程 FROM TB GROUP BY 课程           
        SET @SQL3=N'SELECT * FROM TB PIVOT (MAX(分数) FOR 课程 IN ('+ @SQL3+'))A'
        EXEC@SQL3)

    /*运行结果:
        姓名       语文        数学        物理
        ---------- ----------- ----------- -----------
        张三       74          83          93
        李四       74          84          94
    */

    --行转列结果加上总分、平均分
        --SQL SERVER 2000静态SQL
        BEGIN
            SELECT 
                姓名 
               ,MAX(CASE 课程 
                    WHEN N'语文'  THEN 分数 
                    ELSE 0 
                END) 数学 
               ,MAX(CASE 课程 
                    WHEN N'数学'  THEN 分数 
                    ELSE 0 
                END) 物理 
               ,MAX(CASE 课程 
                    WHEN N'物理'  THEN 分数 
                    ELSE 0 
                END) 语文 
               ,SUM(分数) AS 总分
               ,CAST(AVG(分数*1.0AS DECIMAL(4,2)) AS 平均分
            FROM TB 
            GROUP BY 姓名
        END

        --SQL SERVER 2000动态SQL
        BEGIN
            DECLARE @SQL4 nvarchar(MAX)
            SELECT 
                @SQL4=ISNULL(@SQL4+',','')+N' MAX(CASE 课程 WHEN N'''+课程+N''' THEN 分数 ELSE 0 END)' +课程
            FROM (SELECT 
                      DISTINCT  课程
                  FROM TB 
               ) AS TT
             SET @SQL4=N'SELECT 
                             姓名
                            ,
    '+@SQL4++N',SUM(分数)AS 总分
                            ,CAST(AVG(分数*1.0)AS decimal(4,2)) AS 平均分 
                         FROM TB 
                         GROUP BY 姓名
    '
            PRINT @SQL4
            EXEC(@sql4)
        END
        --SQL SERVER 2005 静态PIVOT
        BEGIN
            SELECT 
                A.*
               ,B.总分
               ,B.平均分 
            FROM (
                    SELECT 
                        * 
                    FROM TB 
                    PIVOT
                    ( 
                         MAX(分数) FOR 课程 IN 
                        ( 
                             数学 
                            ,语文 
                            ,物理 
                        ) 
                    ) AS TT
                 ) AS A 
            INNER JOIN (
                SELECT 
                    姓名
                   ,SUM(分数) AS 总分 
                   ,CAST(AVG(分数*1.0AS decimal(4,2)) AS 平均分 
                FROM TB 
                GROUP BY 姓名
             ) AS B 
                ON A.姓名=B.姓名
        END
        --SQL SERVER 2005 动态PIVOT
        BEGIN
            DECLARE @SQL5 NVARCHAR(MAX)
            SELECT 
                @SQL5=ISNULL(@SQL5+ ',','')+ 课程 
            FROM TB  
            GROUP BY 课程
            SET @SQL5=N'SELECT * FROM TB PIVOT (MAX(分数) FOR 课程 IN ('+@SQL5+')) AS TT'
            SET @SQL5=N'SELECT A.*,B.总分,B.平均分 FROM ('+@SQL5+N') AS A 
            INNER JOIN (SELECT 姓名,SUM(分数) AS 总分,CAST(AVG(分数) AS DECIMAL(4,2)) AS 平均分 FROM TB GROUP BY 姓名) AS B 
            ON A.姓名=B.姓名
    '
                    PRINT @SQL5
            EXEC SP_EXECUTESQL @SQL5
        END
    /*运行结果:
        姓名  语文 数学 物理 总分  平均分
        ----------------- ----------- ----
        李四  74   84   94   252   84.00
        张三  74   83   93   250   83.33
    */
    --另一个例子
    --Create 样例表
    IF OBJECT_ID('TEST'IS NOT NULL
    BEGIN
        DROP TABLE TEST
    END

    CREATE TABLE TEST
    (
         ID INT
        ,Name VARCHAR(20)
        ,[Quarter] INT
        ,[Profile] INT
    )
    --构建样例数据
    INSERT INTO TEST VALUES(1,'A',1,1000)
    INSERT INTO TEST VALUES(1,'A',2,2000)
    INSERT INTO TEST VALUES(1,'A',3,4000)
    INSERT INTO TEST VALUES(1,'A',4,5000)
    INSERT INTO TEST VALUES(1,'B',1,3000)
    INSERT INTO TEST VALUES(1,'B',2,3500)
    INSERT INTO TEST VALUES(1,'B',3,4200)
    INSERT INTO TEST VALUES(1,'B',4,5500)
    --行转换列:四个季度的利润转换成横向显示
    --SQL SERVER 2000 静态SQL
    SELECT 
        ID 
       ,Name 
        ,SUM(CASE [Quarter] 
            WHEN 1 THEN [Profile]
            ELSE 0 
        ENDAS N'1季度' 
        ,SUM(CASE [Quarter] 
                WHEN 2 THEN [Profile]
                ELSE 0 
            ENDAS N'2季度' 
        ,SUM(CASE [Quarter] 
                WHEN 3 THEN [Profile]
                ELSE 0 
            ENDAS N'3季度' 
        ,SUM(CASE [Quarter] 
                WHEN 4 THEN [Profile]
                ELSE 0 
            ENDAS N'4季度' 
    FROM TEST 
    GROUP BY ID,Name
    --SQL SERVER 2005 静态PIVOT
    SELECT 
       *
    FROM TEST 
    PIVOT
    (
         SUM([Profile]FOR [Quarter] IN ([1],[2],[3],[4])
    AS TT


  • 相关阅读:
    Iframe 自适应高度并实时监控高度变化的js代码
    asp.net下载文件几种方式
    C# 使用ffmpeg视频截图
    C# 读取Excel和DBF文件
    C# 多线程下载
    C# http get与post请求方法
    socket实例
    C# 汉字转为拼音
    读取Excel中数据
    【BZOJ2238】Mst 最小生成树+LCA+堆
  • 原文地址:https://www.cnblogs.com/jeriffe/p/1993575.html
Copyright © 2011-2022 走看看