SQL行转列汇总

系统 1431 0

PIVOT 用于将列值旋转为列名(即行转列),在 SQL Server 2000可以用聚合函数配合CASE语句实现

PIVOT 的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P

注意:PIVOT、UNPIVOT是SQL Server 2005 的语法,使用需修改数据库兼容级别( 在数据库属性->选项->兼容级别改为   90 )

SQL2008 中可以直接使用

完整语法:

            
              table_source



PIVOT(



聚合函数(value_column)




            
            
              FOR
            
            
               pivot_column




            
            
              IN
            
            (
            
              <
            
            column_list
            
              >
            
            
              )



)
            
          
View Code

UNPIVOT 用于将列明转为列值(即列转行),在SQL Server 2000可以用UNION来实现

            
              完整语法:



table_source



UNPIVOT(



value_column




            
            
              FOR
            
            
               pivot_column




            
            
              IN
            
            (
            
              <
            
            column_list
            
              >
            
            
              )



)
            
          
View Code

 

典型实例

一、行转列

1 、建立表格

          
            IF
          
          
            OBJECT_ID
          
          (
          
            '
          
          
            tb
          
          
            '
          
          ) 
          
            IS
          
          
            NOT
          
          
            NULL
          
          
            DROP
          
          
            TABLE
          
          
             tb




          
          
            go
          
          
            CREATE
          
          
            TABLE
          
           tb(姓名 
          
            VARCHAR
          
          (
          
            10
          
          ),课程 
          
            VARCHAR
          
          (
          
            10
          
          ),分数 
          
            INT
          
          
            )




          
          
            insert
          
          
            into
          
           tb 
          
            VALUES
          
           (
          
            '
          
          
            张三
          
          
            '
          
          ,
          
            '
          
          
            语文
          
          
            '
          
          ,
          
            74
          
          
            )


          
          
            insert
          
          
            into
          
           tb 
          
            VALUES
          
           (
          
            '
          
          
            张三
          
          
            '
          
          ,
          
            '
          
          
            数学
          
          
            '
          
          ,
          
            83
          
          
            )


          
          
            insert
          
          
            into
          
           tb 
          
            VALUES
          
           (
          
            '
          
          
            张三
          
          
            '
          
          ,
          
            '
          
          
            物理
          
          
            '
          
          ,
          
            93
          
          
            )


          
          
            insert
          
          
            into
          
           tb 
          
            VALUES
          
           (
          
            '
          
          
            李四
          
          
            '
          
          ,
          
            '
          
          
            语文
          
          
            '
          
          ,
          
            74
          
          
            )


          
          
            insert
          
          
            into
          
           tb 
          
            VALUES
          
           (
          
            '
          
          
            李四
          
          
            '
          
          ,
          
            '
          
          
            数学
          
          
            '
          
          ,
          
            84
          
          
            )


          
          
            insert
          
          
            into
          
           tb 
          
            VALUES
          
           (
          
            '
          
          
            李四
          
          
            '
          
          ,
          
            '
          
          
            物理
          
          
            '
          
          ,
          
            94
          
          
            )




          
          
            go
          
          
            SELECT
          
          
            *
          
          
            FROM
          
          
             tb




          
          
            go
          
        

姓名         课程         分数

---------- ---------- -----------

张三         语文         74

张三         数学         83

张三         物理         93

李四         语文         74

李四         数学         84

李四         物理         94

 

2 、使用SQL Server 2000静态SQL

            
              SELECT
            
            
               姓名,



 
            
            
              max
            
            (
            
              CASE
            
             课程 
            
              WHEN
            
            
              '
            
            
              语文
            
            
              '
            
            
              THEN
            
             分数 
            
              ELSE
            
            
              0
            
            
              END
            
            
              ) 语文,



 
            
            
              max
            
            (
            
              CASE
            
             课程 
            
              WHEN
            
            
              '
            
            
              数学
            
            
              '
            
            
              THEN
            
             分数 
            
              ELSE
            
            
              0
            
            
              END
            
            
              ) 数学,



 
            
            
              max
            
            (
            
              CASE
            
             课程 
            
              WHEN
            
            
              '
            
            
              物理
            
            
              '
            
            
              THEN
            
             分数 
            
              ELSE
            
            
              0
            
            
              END
            
            
              ) 物理




            
            
              FROM
            
            
               tb




            
            
              GROUP
            
            
              BY
            
             姓名
          
View Code

3 、使用SQL Server 2000动态SQL

            
              --
            
            
              SQL SERVER 2000动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
            
            
              --
            
            
              变量按sql语言顺序赋值
            
            
              declare
            
            
              @sqlvarchar
            
            (
            
              500
            
            
              )




            
            
              set
            
            
              @sql
            
            
              =
            
            
              '
            
            
              select姓名
            
            
              '
            
            
              select
            
            
              @sql
            
            
              =
            
            
              @sql
            
            
              +
            
            
              '
            
            
              ,max(case课程when 
            
            
              '''
            
            
              +
            
            课程
            
              +
            
            
              '''
            
            
               then分数else 0 end)[
            
            
              '
            
            
              +
            
            课程
            
              +
            
            
              '
            
            
              ]
            
            
              '
            
            
              from
            
            (selectdistinct课程fromtb)a
            
              --
            
            
              同from tb group by课程,默认按课程名排序
            
            
              set
            
            
              @sql
            
            
              =
            
            
              @sql
            
            
              +
            
            
              '
            
            
               from tb group by姓名
            
            
              '
            
            
              exec
            
            (
            
              @sql
            
            
              )



 




            
            
              --
            
            
              使用isnull(),变量先确定动态部分
            
            
              declare
            
            
              @sqlvarchar
            
            (
            
              8000
            
            
              )




            
            
              select
            
            
              @sql
            
            
              =
            
            
              isnull
            
            (
            
              @sql
            
            
              +
            
            
              '
            
            
              ,
            
            
              '
            
            ,
            
              ''
            
            )
            
              +
            
            
              '
            
            
               max(case课程when 
            
            
              '''
            
            
              +
            
            课程
            
              +
            
            
              '''
            
            
               then分数else 0 end) [
            
            
              '
            
            
              +
            
            课程
            
              +
            
            
              '
            
            
              ]
            
            
              '
            
            
              from
            
            
              (selectdistinct课程fromtb)asa      




            
            
              set
            
            
              @sql
            
            
              =
            
            
              '
            
            
              select姓名,
            
            
              '
            
            
              +
            
            
              @sql
            
            
              +
            
            
              '
            
            
               from tb group by姓名
            
            
              '
            
            
              exec
            
            (
            
              @sql
            
            )
          
View Code

4 、使用SQL Server 2005静态SQL

          
            SELECT
          
          
            *
          
          
            FROM
          
           tb pivot( 
          
            MAX
          
          (分数) 
          
            FOR
          
           课程 
          
            IN
          
           (语文,数学,物理))a
        

姓名         语文          数学          物理

---------- ----------- ----------- -----------

李四         74          84          94

张三         74          83          93

5、 使用SQL Server 2005动态SQL

          
            --
          
          
            使用stuff()
          
          
            DECLARE
          
          
            @sql
          
          
            VARCHAR
          
          (
          
            8000
          
          
            )




          
          
            SET
          
          
            @sql
          
          
            =
          
          
            ''
          
          
            --
          
          
            初始化变量 @sql
          
          
            SELECT
          
          
            @sql
          
          
            =
          
          
            @sql
          
          
            +
          
          
            '
          
          
            ,
          
          
            '
          
          
            +
          
           课程 
          
            FROM
          
           tb 
          
            GROUP
          
          
            BY
          
           课程 
          
            --
          
          
            变量多值赋值
          
          
            SET
          
          
            @sql
          
          
            =
          
          
            STUFF
          
          (
          
            @sql
          
          ,
          
            1
          
          ,
          
            1
          
          ,
          
            ''
          
          )
          
            --
          
          
            去掉首个','
          
          
            SET
          
          
            @sql
          
          
            =
          
          
            '
          
          
            select * from tb pivot (max(分数) for 课程 in (
          
          
            '
          
          
            +
          
          
            @sql
          
          
            +
          
          
            '
          
          
            ))a
          
          
            '
          
          
            PRINT
          
          
            @sql
          
          
            exec
          
          (
          
            @sql
          
          
            )




          
          
            --
          
          
            或使用isnull()
          
          
            DECLARE
          
          
            @sql
          
          
            VARCHAR
          
          (
          
            8000
          
          
            )




          
          
            --
          
          
            获得课程集合
          
          
            SELECT
          
          
            @sql
          
          
            =
          
          
            ISNULL
          
          (
          
            @sql
          
          
            +
          
          
            '
          
          
            ,
          
          
            '
          
          ,
          
            ''
          
          )
          
            +
          
          课程 
          
            FROM
          
          
             tb


          
          
            GROUP
          
          
            BY
          
          
             课程           




          
          
            SET
          
          
            @sql
          
          
            =
          
          
            '
          
          
            select * from tb pivot (max(分数) for 课程 in (
          
          
            '
          
          
            +
          
          
            @sql
          
          
            +
          
          
            '
          
          
            ))a
          
          
            '
          
          
            exec
          
          (
          
            @sql
          
          )
        

二、行转列结果加上总分、平均分

1 、使用SQL Server 2000静态SQL

            
              --
            
            
              SQL SERVER 2000静态SQL
            
            
              

select姓名,




            
            
              max
            
            (case课程when
            
              '
            
            
              语文
            
            
              '
            
            
              then分数else0end)语文,




            
            
              max
            
            (case课程when
            
              '
            
            
              数学
            
            
              '
            
            
              then分数else0end)数学,




            
            
              max
            
            (case课程when
            
              '
            
            
              物理
            
            
              '
            
            
              then分数else0end)物理,




            
            
              sum
            
            
              (分数)总分,




            
            
              cast
            
            (
            
              avg
            
            (分数
            
              *
            
            
              1.0
            
            )asdecimal(
            
              18
            
            ,
            
              2
            
            
              ))平均分



fromtb



groupby姓名
            
          
View Code

姓名         语文          数学          物理          总分          平均分

---------- ----------- ----------- ----------- -----------

李四         74          84          94          252         84.00

张三         74          83          93          250         83.33

 

2 、使用SQL Server 2000动态SQL

            
              --
            
            
              SQL SERVER 2000动态SQL
            
            
              declare
            
            
              @sqlvarchar
            
            (
            
              500
            
            
              )




            
            
              set
            
            
              @sql
            
            
              =
            
            
              '
            
            
              select姓名
            
            
              '
            
            
              select
            
            
              @sql
            
            
              =
            
            
              @sql
            
            
              +
            
            
              '
            
            
              ,max(case课程when 
            
            
              '''
            
            
              +
            
            课程
            
              +
            
            
              '''
            
            
               then分数else 0 end)[
            
            
              '
            
            
              +
            
            课程
            
              +
            
            
              '
            
            
              ]
            
            
              '
            
            
              from
            
            
              (selectdistinct课程fromtb)a




            
            
              set
            
            
              @sql
            
            
              =
            
            
              @sql
            
            
              +
            
            
              '
            
            
              ,sum(分数)总分,cast(avg(分数*1.0) as decimal(18,2))      平均分from tb group by姓名
            
            
              '
            
            
              exec
            
            (
            
              @sql
            
            )
          
View Code

 

3 、使用SQL Server 2005静态SQL

          
            SELECT
          
            m.
          
            *
          
          
             ,

        n.总分 ,

        n.平均分


          
          
            FROM
          
              ( 
          
            SELECT
          
          
            *
          
          
            FROM
          
                tb PIVOT( 
          
            MAX
          
          (分数) 
          
            FOR
          
           课程 
          
            IN
          
          
             ( 语文, 数学, 物理 ) ) a

        ) m ,

        ( 
          
          
            SELECT
          
          
                姓名 ,

                    
          
          
            SUM
          
          
            (分数) 总分 ,

                    
          
          
            CAST
          
          (
          
            AVG
          
          (分数 
          
            *
          
          
            1.0
          
          ) 
          
            AS
          
          
            DECIMAL
          
          (
          
            18
          
          , 
          
            2
          
          
            )) 平均分

          
          
          
            FROM
          
          
                  tb

          
          
          
            GROUP
          
          
            BY
          
          
              姓名

        ) n


          
          
            WHERE
          
             m.姓名 
          
            =
          
           n.姓名
        

4 、使用SQL Server 2005动态SQL

            
              --
            
            
              使用stuff()
            
            
              DECLARE
            
            
              @sql
            
            
              VARCHAR
            
            (
            
              8000
            
            
              )




            
            
              SET
            
            
              @sql
            
            
              =
            
            
              ''
            
            
              --
            
            
              初始化变量@sql
            
            
              SELECT
            
            
              @sql
            
            
              =
            
            
              @sql
            
            
              +
            
            
              '
            
            
              ,
            
            
              '
            
            
              +
            
            
               课程


            
            
              FROM
            
            
                  tb


            
            
              GROUP
            
            
              BY
            
            
               课程


            
            
              --
            
            
              变量多值赋值
            
            
              --
            
            
              同select @sql = @sql + ','+课程 from (select distinct 课程 from tb)a
            
            
              SET
            
            
              @sql
            
            
              =
            
            
              STUFF
            
            (
            
              @sql
            
            , 
            
              1
            
            , 
            
              1
            
            , 
            
              ''
            
            
              )


            
            
              --
            
            
              去掉首个','
            
            
              SET
            
            
              @sql
            
            
              =
            
            
              '
            
            
               select m.* , n.总分,n.平均分 from



(select * from (select * from tb) a pivot (max(分数) for 课程 in (
            
            
              '
            
            
              +
            
            
              @sql
            
            
              +
            
            
              '
            
            
              )) b) m ,



(select 姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2)) 平均分 from tb group by 姓名) n



where m.姓名= n.姓名
            
            
              '
            
            
              EXEC
            
            (
            
              @sql
            
            
              )

 




            
            
              --
            
            
              或使用isnull()
            
            
              DECLARE
            
            
              @sql
            
            
              VARCHAR
            
            (
            
              8000
            
            
              )




            
            
              SELECT
            
            
              @sql
            
            
              =
            
            
              ISNULL
            
            (
            
              @sql
            
            
              +
            
            
              '
            
            
              ,
            
            
              '
            
            , 
            
              ''
            
            ) 
            
              +
            
            
               课程


            
            
              FROM
            
            
                  tb


            
            
              GROUP
            
            
              BY
            
            
               课程




            
            
              SET
            
            
              @sql
            
            
              =
            
            
              '
            
            
              select m.* , n.总分,n.平均分 from



(select * from (select * from tb) a pivot (max(分数) for 课程 in (
            
            
              '
            
            
              +
            
            
              @sql
            
            
              +
            
            
              '
            
            
              )) b) m ,



(select 姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2)) 平均分 from tb group by 姓名) n



where m.姓名= n.姓名
            
            
              '
            
            
              EXEC
            
            (
            
              @sql
            
            )
          
View Code

 

二、列转行

1 、建立表格

          
            IF
          
          
            OBJECT_ID
          
          (
          
            '
          
          
            tb
          
          
            '
          
          ) 
          
            IS
          
          
            NOT
          
          
            NULL
          
          
            DROP
          
          
            TABLE
          
          
             tb


          
          
            go
          
          
            CREATE
          
          
            TABLE
          
           tb(姓名 
          
            VARCHAR
          
          (
          
            10
          
          ),语文 
          
            INT
          
          ,数学 
          
            INT
          
          ,物理 
          
            INT
          
          
            )




          
          
            INSERT
          
          
            INTO
          
           tb 
          
            VALUES
          
          (
          
            '
          
          
            张三
          
          
            '
          
          ,
          
            74
          
          ,
          
            83
          
          ,
          
            93
          
          
            )




          
          
            INSERT
          
          
            INTO
          
           tb 
          
            VALUES
          
          (
          
            '
          
          
            李四
          
          
            '
          
          ,
          
            74
          
          ,
          
            84
          
          ,
          
            94
          
          
            )




          
          
            go
          
          
            SELECT
          
          
            *
          
          
            FROM
          
           tb
        

姓名         语文          数学          物理

---------- ----------- ----------- -----------

张三        74          83          93

李四         74          84          94

2 、使用SQL Server 2000静态SQL

            
              --
            
            
              SQL SERVER 2000静态SQL。
            
            
              select
            
            
              *
            
            
              from
            
            
              



(



 select姓名,课程
            
            
              =
            
            
              '
            
            
              语文
            
            
              '
            
            ,分数
            
              =
            
            
              语文fromtb



 unionall



 select姓名,课程
            
            
              =
            
            
              '
            
            
              数学
            
            
              '
            
            ,分数
            
              =
            
            
              数学fromtb



 unionall



 select姓名,课程
            
            
              =
            
            
              '
            
            
              物理
            
            
              '
            
            ,分数
            
              =
            
            
              物理fromtb



) t



orderby姓名,case课程when
            
            
              '
            
            
              语文
            
            
              '
            
            then1when
            
              '
            
            
              数学
            
            
              '
            
            then2when
            
              '
            
            
              物理
            
            
              '
            
            then3end
          
View Code

姓名         课程   分数

---------- ---- -----------

李四         语文  74

李四         数学  84

李四         物理  94

张三         语文  74

张三         数学  83

张三         物理  93

  

2 、使用SQL Server 2000动态SQL

            
              --
            
            
              SQL SERVER 2000动态SQL。
            
            
              --
            
            
              调用系统表动态生态。
            
            
              declare
            
            
              @sqlvarchar
            
            (
            
              8000
            
            
              )




            
            
              select
            
            
              @sql
            
            
              =
            
            
              isnull
            
            (
            
              @sql
            
            
              +
            
            
              '
            
            
               union all 
            
            
              '
            
            ,
            
              ''
            
            )
            
              +
            
            
              '
            
            
               select姓名, [课程]=
            
            
              '
            
            
              +
            
            
              quotename
            
            (Name,
            
              ''''
            
            )
            
              +
            
            
              '
            
            
               , [分数] = 
            
            
              '
            
            
              +
            
            
              quotename
            
            (Name)
            
              +
            
            
              '
            
            
               from tb
            
            
              '
            
            
              



fromsyscolumns



whereName
            
            
              !=
            
            
              '
            
            
              姓名
            
            
              '
            
            andID
            
              =
            
            
              object_id
            
            (
            
              '
            
            
              tb
            
            
              '
            
            )
            
              --
            
            
              表名tb,不包含列名为姓名的其他列
            
            
              

orderbycolid




            
            
              exec
            
            (
            
              @sql
            
            
              +
            
            
              '
            
            
               order by姓名
            
            
              '
            
            
              )




            
            
              go
            
          
View Code

 

3 、使用SQL Server 2005静态SQL

          
            --
          
          
            SQL SERVER 2005动态SQL
          
          
            SELECT
          
          
              姓名 ,

        课程 ,

        分数


          
          
            FROM
          
              tb UNPIVOT ( 分数 
          
            FOR
          
           课程 
          
            IN
          
           ( 
          
            [
          
          
            语文
          
          
            ]
          
          , 
          
            [
          
          
            数学
          
          
            ]
          
          , 
          
            [
          
          
            物理
          
          
            ]
          
           ) ) t 
        

4 、使用SQL Server 2005动态SQL

          
            --
          
          
            SQL SERVER 2005动态SQL
          
          
            DECLARE
          
          
            @sql
          
          
            NVARCHAR
          
          (
          
            4000
          
          
            )




          
          
            SELECT
          
          
            @sql
          
          
            =
          
          
            ISNULL
          
          (
          
            @sql
          
          
            +
          
          
            '
          
          
            ,
          
          
            '
          
          , 
          
            ''
          
          ) 
          
            +
          
          
            QUOTENAME
          
          
            (name)


          
          
            FROM
          
          
                syscolumns


          
          
            WHERE
          
             id 
          
            =
          
          
            OBJECT_ID
          
          (
          
            '
          
          
            tb
          
          
            '
          
          
            )

        
          
          
            AND
          
           name 
          
            NOT
          
          
            IN
          
           ( 
          
            '
          
          
            姓名
          
          
            '
          
          
             )


          
          
            ORDER
          
          
            BY
          
          
             colid




          
          
            SET
          
          
            @sql
          
          
            =
          
          
            '
          
          
            select 姓名,[课程],[分数] from tb unpivot ([分数] for [课程] in(
          
          
            '
          
          
            +
          
          
            @sql
          
          
            +
          
          
            '
          
          
            ))b
          
          
            '
          
          
            EXEC
          
          (
          
            @sql
          
          
            )




          
        

 

来自大神张志涛

SQL行转列汇总


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论