zoukankan      html  css  js  c++  java
  • 【转载】SQLServer2005 Pivot 转置使用动态列

    转载自:http://www.cbf107.com/CBF107Item.aspx?ID=79c98c3e-aea2-46f9-baa7-1ccd067e2a81
    SQLServer2005 Pivot
    转置使用动态列(应用到视图)

    最近项目中用到Pivot 对表进行转置,遇到一些问题,主要是Pivot 转置的时候没有办法动态产生转置列名,而作视图的时候又很需要动态的产生这些列,百度上似乎也没有找的很满意的答案,在google上搜到一老外的解决方案,现在自己总结了一下,希望给用的上的朋友一些帮助。

    http://www.cbf107.com/images/pivot20080719001.gif

     

    1.创建表脚本

     

    if exists (select 1

                from  sysobjects

               where  id = object_id('Insurances')

                and   type = 'U')

       drop table Insurances

    go

     

    /*==============================================================*/

    /* Table: Insurances                                            */

    /*==============================================================*/

    create table Insurances (

       RefID                uniqueidentifier     not null,

       HRMS                 nvarchar(20)         null,

       Name                 nvarchar(20)         null,

       InsuranceMoney       money                null,

       InsuranceName        nvarchar(100)        not null,

       constraint PK_INSURANCES primary key (RefID)

    )

    go

     

     

    2.测试数据脚本

     

    insert into Insurances values (newid(),1,'张三',200,'养老保险')

    insert into Insurances values (newid(),1,'张三',300,'医疗保险')

    insert into Insurances values (newid(),2,'李四',250,'养老保险')

    insert into Insurances values (newid(),2,'李四',350,'医疗保险')

    insert into Insurances values (newid(),3,'王二',150,'养老保险')

    insert into Insurances values (newid(),3,'王二',300,'医疗保险')

     

    3.查询表数据

     

    select HRMS,Name,InsuranceMoney,InsuranceName From Insurances

     

    HRMS                 Name                 InsuranceMoney        InsuranceName

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

    1                    张三                  200.00                养老保险

    2                    李四                  350.00                医疗保险

    2                    李四                  250.00                养老保险

    1                    张三                  300.00                医疗保险

    3                    王二                  300.00                医疗保险

    3                    王二                  150.00                养老保险

     

    4.转置表数据

     

    select * from

    (

    select HRMS,Name,InsuranceMoney,InsuranceName from Insurances

    ) p

    Pivot (

    sum(InsuranceMoney)

    FOR InsuranceName IN

    ( [医疗保险], [养老保险]))

    as pvt

     

     

    HRMS                 Name                 医疗保险                 养老保险

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

    2                    李四                  350.00                250.00

    3                    王二                  300.00                150.00

    1                    张三                  300.00                200.00

     

    5.偶的问题

     

     http://www.cbf107.com/images/pivot20080719002.gif

    这个语句中 医疗保险、养老保险 SQL语句中写死的,而且Sql2005中这个代码没有办法使用动态的查询结果集

     

    5.存储过程解决问题

     

    所以如果要动态的完成个脚本,可以先拼出SQL 然后通过exec sp_executesql 执行

     

    实现存储过程

     

    create procedure InsurancePivot

    as

    Begin

        DECLARE @ColumnNames VARCHAR(3000)

     

        SET @ColumnNames=''

     

        SELECT

           @ColumnNames = @ColumnNames + '[' + InsuranceName + '],'

        FROM

           (

           SELECT DISTINCT InsuranceName FROM Insurances

           ) t

     

        SET @ColumnNames= LEFT(@ColumnNames, LEN(@ColumnNames)-1)

     

        DECLARE @selectSQL NVARCHAR(3000)

     

        SET @selectSQL=

        'SELECT HRMS,Name,{0} FROM

           (

           SELECT HRMS,Name,InsuranceMoney,InsuranceName FROM Insurances

           ) p

         Pivot( Max(InsuranceMoney)  For InsuranceName in ({0})) AS pvt

           ORDER BY HRMS'

     

        SET @selectSQL= REPLACE(@selectSQL,'{0}',@ColumnNames)

     

        exec sp_executesql @selectSQL

    end

     

    测试存储过程:

     

    exec InsurancePivot

     

    HRMS                 Name                 养老保险                 医疗保险

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

    1                    张三                  200.00                300.00

    2                    李四                  250.00                350.00

    3                    王二                  150.00                300.00

     

     

    6.关于视图的新问题和解决方案

     

    在视图中没有办法直接调用这个存储过程,但是我们在做程序、做报表的时候又非常需要

     

    其实可以通过OPENQUERY来实现(这是一个非正规的解决方式,但目前可以实现)

    (另外可以使用OPENROWSET,但是参数太多偶放弃了)

     

    使用OPENQUERY 的格式是:OPENQUERY([链接服务器],’sql语句’)

    因为是当前数据的视图, 链接服务器可以通过属性查看,MSCBF107 是我测试的链接服务器

    http://www.cbf107.com/images/pivot20080719003.gif

    http://www.cbf107.com/images/pivot20080719004.gif

    也可以通过sp_helpserver 查看

     

    http://www.cbf107.com/images/pivot20080719006.gif

    下面这句话也非常重要,使用的朋友替换[MSCBF107]ok了,否则使用OPENQUERY会出现未将服务器'MSCBF107' 配置为用于DATA ACCESS

     

    sp_serveroption [MSCBF107], 'Data Access', 'True'

     

    创建视图如下:

     

     

    create view InsurancePivotView

    as

    select *From OPENQUERY ([MSCBF107],N'SET FMTONLY OFF;exec test.dbo.InsurancePivot')

     

     

    测试视图就可以得到想要的结果了

     

    select *from InsurancePivotView

    That’s all

  • 相关阅读:
    基础总结篇之一:Activity生命周期
    putExtra方法
    fork函数
    linux中fork()函数详解(原创!!实例讲解) (转载)
    系统调用wait、waitpid和exec函数
    版本控制工具VSS使用介绍
    学习进度条六(第七周)
    阶段冲刺4
    阶段冲刺3
    阶段冲刺2
  • 原文地址:https://www.cnblogs.com/icebutterfly/p/1541322.html
Copyright © 2011-2022 走看看