SQL行列互換

 面試的時候遇到的數據庫SQL問題,沒寫過,然後研究了一下,現將結果記錄下來,方便以後查詢。
 
題目1:將表tbltest1的行列互換
 
表結構:
student     kemu  fenshu
student1    語文    80
student1    數學    90
student1    英語    85
student2    語文    85
student2    數學    92
student2    英語    82
 
變成:
student  語文    數學   英語
student1   80     90     85
student2   85     92     82
 
SQLserver的sql語句:
declare @sql varchar(4000)  
set @sql = 'select student'  
select @sql = @sql + ',sum(case kemu when '''+ kemu +''' then fenshu else 0 end)['+ kemu+']'
  from (select distinct kemu from tbltest1) as a  
set @sql = @sql + ' from tbltest1 group by student'  
exec(@sql)
或者
select student,sum(case kemu when '語文' then fenshu else 0 end) 語文,sum(case kemu when '數學' then fenshu else 0 end) 數學,sum(case kemu when '英語' then fenshu else 0 end) 英語 from tbltest group by student
 
注:個人覺得上面的好。如果一兩個選項可以使用下面的sql,如果選項多上面的sql就顯的方便的多。
 
2005的話好像還有個函數可以用,等研究好了再發上來。
 
題目2:合併
 
表結構tbltest2:
id strings
1   my
1   name
1   is
1   xudayu
2   hello
2   world
 
轉化成:
id   strings
 1   my name is xudayu 
 2   hello world 
 
SQLServer的sql語句:
 
--創建一個合併的函數  
create function fliehebin(@id int)  
returns varchar(5000)  
as  
begin  
declare @str varchar(5000)  
set @str=''  
select @str=@str + cast(strings as varchar(50)) +' ' from tbltest2 where id=@id  
set @str=subString(@str,1,len(@str))  
return(@str)  
end  
go  
--調用自定義函數得到結果
select distinct id,dbo.fliehebin(id) from tbltest2

 

 

 

 =====================================================================

傳說通用的, 如下:

 

  1. IF   EXISTS(   select     *     from   sysobjects   where   xtype='U'and   name   ='data2'   )     
  2.   Begin     
  3.   Drop   table     data2       
  4.   End       
  5.       
  6.       
  7.   CREATE   TABLE   [data2]   (     
  8.     [人員編號]   [varchar]   (10)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL   ,     
  9.     [基本工資]   [numeric](18,   2)   NULL   ,     
  10.     [獎金]   [numeric](18,   2)   NULL   ,     
  11.     [合計]   [numeric](19,   2)   NULL   ,     
  12.     CONSTRAINT   [PK_data2]   PRIMARY   KEY     CLUSTERED       
  13.     (     
  14.       [人員編號]     
  15.     )     ON   [PRIMARY]       
  16.   )   ON   [PRIMARY]     
  17.   GO     
  18.       
  19.   insert   data2   select   'a1',1.00,11.00,111.00     
  20.   insert   data2   select   'a2',2.00,22.00,222.00     
  21.   insert   data2   select   'a3',3.00,33.00,333.00     
  22.   insert   data2   select   'a100',100.00,100.00,100.00     
  23.       
  24.   go     
  25.   drop       PROCEDURE   AVB_IniTable     
  26.   go     
  27.   /*    
  28.   author:nyb    
  29.   time     :2005/04/22    
  30.   fixtime :    
  31.   aim       :轉置行和列    
  32.   input   :@TableNane    
  33.   執行:    
  34.   EXECUTE   AVB_IniTable   'data2'    
  35.   */     
  36.       
  37.   Create       PROCEDURE   AVB_IniTable     
  38.   @TableNane   varchar(128)     
  39.       
  40.   AS     
  41.   DECLARE   @string   VARCHAR(8000)     
  42.   --1   創建View     
  43.   IF   EXISTS(   select     *     from   sysobjects   where   xtype='V'and   name   ='V_Temp'   )     
  44.   Begin     
  45.   Drop   view     V_Temp       
  46.   End       
  47.       
  48.   SELECT   @string   =   '   Create   view   V_Temp   as     select   *     from   '   +   @TableNane       
  49.   EXECUTE   (@string)     
  50.       
  51.   IF   EXISTS(   select     *     from   sysobjects   where   xtype='U'and   name   ='zzTemp'   )     
  52.   Begin     
  53.   Drop   table     zzTemp       
  54.   End       
  55.       
  56.       
  57.   DECLARE   @ColumnName   VARCHAR(200)     
  58.   DECLARE   @ColumnStr   VARCHAR(5000)     
  59.   select   @ColumnStr=   ''     
  60.   select   @ColumnStr=@ColumnStr   +   quotename(rtrim(人員編號))   +'float   NULL,'   from   V_Temp       
  61.   print   @ColumnStr     
  62.       
  63.   SET   @ColumnStr   =   left(@ColumnStr,len(@ColumnStr)-1)     
  64.   SELECT   @string   =   'CREATE   TABLE   zzTemp   (列名   varchar(50)   NULL,'   +     @ColumnStr   +   ')   ON   [PRIMARY]'     
  65.   print   @string     
  66.   EXECUTE   (@string)     
  67.       
  68.   --2插入記錄     
  69.   DECLARE   Column_cur     SCROLL   CURSOR   FOR     
  70.   SELECT   name   FROM   syscolumns   WHERE   ID=object_id(@TableNane)   and   name   <>'人員編號'     
  71.   OPEN     Column_cur       
  72.   FETCH   FIRST   FROM     Column_cur   into   @ColumnName     
  73.   WHILE   (@@fetch_status<>-1)     
  74.   BEGIN     
  75.   select   @ColumnStr=   ''     
  76.   if   @ColumnName   =   '基本工資'     
  77.   select   @ColumnStr=   @ColumnStr   +   ''''   +   convert(varchar(20),ISNULL(基本工資,0))   +   ''','   from   V_Temp         
  78.   else   if   @ColumnName   =   '獎金'     
  79.   select   @ColumnStr=   @ColumnStr   +   ''''   +   convert(varchar(20),ISNULL(獎金,0))   +   ''','   from   V_Temp         
  80.   else   if   @ColumnName   =   '合計'     
  81.   select   @ColumnStr=   @ColumnStr   +   ''''   +   convert(varchar(20),ISNULL(合計,0))   +   ''','   from   V_Temp         
  82.       
  83.     SET   @ColumnStr   =   left(@ColumnStr,len(@ColumnStr)-1)     
  84.     select   @string   =   'insert   into   zzTemp   values('''   +   @ColumnName   +   ''','   +     @ColumnStr   +')'     
  85.   execute(@string)     
  86.   FETCH   NEXT   FROM     Column_cur   into   @ColumnName     
  87.   END     
  88.   CLOSE   Column_cur     
  89.   DEALLOCATE   Column_cur     
  90.       
  91.       
  92.   go     
  93.   --察看結果     
  94.   select   *   from   data2     
  95.   select   *   from   zzTemp   

 

 

 =====================================================================

  1. if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[dbo].[p_zj]')   and   OBJECTPROPERTY(id,   N'IsProcedure')   =   1)     
  2.   drop   procedure   [dbo].[p_zj]     
  3.   GO     
  4.       
  5.   /*--行列互換的通用存儲過程    
  6.      
  7.   將指定的表,按指定的字段進行行列互換    
  8.      
  9.   --鄒建   2004.04--*/     
  10.       
  11.   /*--使用示例    
  12.      
  13.   --測試數據    
  14.   create   table   表(類別   varchar(10),男性   decimal(20,1),女性   decimal(20,1))    
  15.   insert   表   select   '小說',38.0,59.2    
  16.   union   all   select   '散文',18.9,30.6    
  17.   union   all   select   '哲學',16.2,10.2    
  18.      
  19.   /*--要求轉換結果    
  20.   性別       小說         散文         哲學            
  21.   ----   -----   -----   -----      
  22.   男性       38.0     18.9     16.2    
  23.   女性       59.2     30.6     10.2    
  24.      
  25.   (所影響的行數爲   2   行)    
  26.   --*/     
  27.       
  28.   --調用存儲過程     
  29.   exec   p_zj   '表','類別','性別'     
  30.       
  31.   --刪除測試     
  32.   drop   table   表     
  33.   --*/     
  34.   create   proc   p_zj     
  35.   @tbname   sysname, --要處理的表名     
  36.   @fdname   sysname, --做爲轉換的列名     
  37.   @new_fdname   sysname='' --爲轉換後的列指定列名     
  38.   as     
  39.   declare   @s1   varchar(8000),@s2   varchar(8000)     
  40.   ,@s3   varchar(8000),@s4   varchar(8000),@s5   varchar(8000)     
  41.   ,@i   varchar(10)     
  42.   select   @s1='',@s2='',@s3='',@s4='',@s5='',@i='0'     
  43.   select   @s1=@s1+',@'+@i+'   varchar(8000)'     
  44.   ,@s2=@s2+',@'+@i+'='''+case   isnull(@new_fdname,'')   when   ''   then   ''     
  45.   else   @new_fdname+'='   end+''''''+name+''''''''     
  46.   ,@s3=@s3+'     
  47.   select   @'+@i+'=@'+@i+'+'',[''+cast(['+@fdname+']   as   varchar)+'']=''''''+replace(['+name+'],'''','''''''')+''''''''   from   ['+@tbname+']'     
  48.   ,@s4=@s4+',@'+@i+'=''select   ''+@'+@i     
  49.   ,@s5=@s5+'+''   union   all   ''+@'+@i     
  50.   ,@i=cast(@i   as   int)+1     
  51.   from   syscolumns       
  52.   where   object_id(@tbname)=id   and   name<>@fdname     
  53.   order   by   colid     
  54.       
  55.   select   @s1=substring(@s1,2,8000)     
  56.   ,@s2=substring(@s2,2,8000)     
  57.   ,@s4=substring(@s4,2,8000)     
  58.   ,@s5=substring(@s5,16,8000)     
  59.       
  60.   exec('declare   '+@s1+'     
  61.   select   '+@s2+@s3+'     
  62.   select   '+@s4+'     
  63.   exec('+@s5+')')     
  64.   go  

 

 

Oracle's:

 

 

  1. 最近公司項目涉及到統計報表,有關交叉報表部分差不多都有行列轉換需求,根據個人開發中的需求,總結了一些例子  
  2.   
  3. 1.創建表  
  4.   
  5. create table T1  
  6. (  
  7.   PRODUCTID VARCHAR2(100),  
  8.   NUM       NUMBER  
  9. )  
  10. ;  
  11.   
  12. 2.插入測試數據  
  13.   
  14. insert into T1 (PRODUCTID, NUM)  
  15. values ('1'3);  
  16. insert into T1 (PRODUCTID, NUM)  
  17. values ('2'12);  
  18. insert into T1 (PRODUCTID, NUM)  
  19. values ('3'24);  
  20. insert into T1 (PRODUCTID, NUM)  
  21. values ('4'11);  
  22. insert into T1 (PRODUCTID, NUM)  
  23. values ('5'51);  
  24. insert into T1 (PRODUCTID, NUM)  
  25. values ('6'511);  
  26. commit;  
  27.   
  28. 3.編寫轉換函數  
  29.   
  30. CREATE OR REPLACE FUNCTION fn_rs_1  
  31.     RETURN pkg_getrecord.myrctype  
  32. IS  
  33.     s VARCHAR2 (4000);  
  34.     CURSOR c1 IS  
  35.     SELECT ',sum(case when productid!='|| productid || ' then num else 0 end)' || ' "產品' || productid|| '"' c2  
  36.     FROM t1  
  37.     group by productid;  
  38.     r1 c1%ROWTYPE;  
  39.     list_cursor pkg_getrecord.myrctype;  
  40. BEGIN  
  41.     s := 'select  1 ';  
  42.     OPEN c1;  
  43.     LOOP  
  44.         FETCH c1 INTO r1;  
  45.         EXIT WHEN c1%NOTFOUND;  
  46.         s := s || r1.c2;  
  47.     END LOOP;  
  48.     CLOSE c1;  
  49.     s := s || ' from t1 g ';  
  50.     dbms_output.put_line(s);  
  51.     OPEN list_cursor FOR s;  
  52.     RETURN list_cursor;  
  53. END fn_rs_1;  
  54.   
  55. 4.java測試代碼  
  56.   
  57. public class Test {  
  58.  private String db_url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";  
  59.  private String db_username = "test";  
  60.  private String db_passwd = "test";  
  61.   
  62.  /** 
  63.   * @param args 
  64.   */  
  65.  public static void main(String[] args) {  
  66.   Test test=new Test();  
  67.   try {  
  68.    test.exec();  
  69.   } catch (SQLException e) {  
  70.    e.printStackTrace();  
  71.   }  
  72.  }  
  73.   
  74.  public void exec() throws SQLException {  
  75.   Connection conn = getConnection();  
  76.   if(conn==null){  
  77.    throw new SQLException("database not connectioned");  
  78.   }  
  79.   CallableStatement cstmt = conn.prepareCall("{?=call fn_rs_1}");  
  80.   cstmt.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);  
  81.   cstmt.execute();  
  82.   ResultSet rs=(ResultSet)cstmt.getObject(1);  
  83.   if(rs.next()){  
  84.    for(int j=1;j<=rs.getMetaData().getColumnCount();j++){  
  85.     System.out.print(rs.getMetaData().getColumnName(j)+"/t");  
  86.    }  
  87.   }  
  88.   System.out.println("");  
  89.   cstmt.execute();  
  90.   rs=(ResultSet)cstmt.getObject(1);  
  91.   while(rs.next()){  
  92.    System.out.print(rs.getString(1)+"/t");  
  93.    System.out.print(rs.getString(2)+"/t");  
  94.    System.out.print(rs.getString(3)+"/t");  
  95.    System.out.print(rs.getString(4)+"/t");  
  96.    System.out.print(rs.getString(5)+"/t");  
  97.    System.out.print(rs.getString(6)+"/t");  
  98.    System.out.print(rs.getString(7)+"/t");  
  99.   }  
  100.   cstmt.close();  
  101.  }  
  102.   
  103.  protected Connection getConnection() {  
  104.   try {  
  105.    Class.forName("oracle.jdbc.driver.OracleDriver");  
  106.    return DriverManager.getConnection(db_url, db_username, db_passwd);  
  107.   } catch (ClassNotFoundException e) {  
  108.    e.printStackTrace();  
  109.   } catch (SQLException e) {  
  110.    e.printStackTrace();  
  111.   }  
  112.   return null;  
  113.  }  
  114.   
  115. }  
  116.   
  117.   
  118. 本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/jianping_shen/archive/2009/04/01/4041169.aspx 
     面試的時候遇到的數據庫SQL問題,沒寫過,然後研究了一下,現將結果記錄下來,方便以後查詢。
     
    題目1:將表tbltest1的行列互換
     
    表結構:
    student     kemu  fenshu
    student1    語文    80
    student1    數學    90
    student1    英語    85
    student2    語文    85
    student2    數學    92
    student2    英語    82
     
    變成:
    student  語文    數學   英語
    student1   80     90     85
    student2   85     92     82
     
    SQLserver的sql語句:
    declare @sql varchar(4000)  
    set @sql = 'select student'  
    select @sql = @sql + ',sum(case kemu when '''+ kemu +''' then fenshu else 0 end)['+ kemu+']'
      from (select distinct kemu from tbltest1) as a  
    set @sql = @sql + ' from tbltest1 group by student'  
    exec(@sql)
    或者
    select student,sum(case kemu when '語文' then fenshu else 0 end) 語文,sum(case kemu when '數學' then fenshu else 0 end) 數學,sum(case kemu when '英語' then fenshu else 0 end) 英語 from tbltest group by student
     
    注:個人覺得上面的好。如果一兩個選項可以使用下面的sql,如果選項多上面的sql就顯的方便的多。
     
    2005的話好像還有個函數可以用,等研究好了再發上來。
     
    題目2:合併
     
    表結構tbltest2:
    id strings
    1   my
    1   name
    1   is
    1   xudayu
    2   hello
    2   world
     
    轉化成:
    id   strings
     1   my name is xudayu 
     2   hello world 
     
    SQLServer的sql語句:
     
    --創建一個合併的函數  
    create function fliehebin(@id int)  
    returns varchar(5000)  
    as  
    begin  
    declare @str varchar(5000)  
    set @str=''  
    select @str=@str + cast(strings as varchar(50)) +' ' from tbltest2 where id=@id  
    set @str=subString(@str,1,len(@str))  
    return(@str)  
    end  
    go  
    --調用自定義函數得到結果
    select distinct id,dbo.fliehebin(id) from tbltest2

     

     

     

     =====================================================================

    傳說通用的, 如下:

     

    1. IF   EXISTS(   select     *     from   sysobjects   where   xtype='U'and   name   ='data2'   )     
    2.   Begin     
    3.   Drop   table     data2       
    4.   End       
    5.       
    6.       
    7.   CREATE   TABLE   [data2]   (     
    8.     [人員編號]   [varchar]   (10)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL   ,     
    9.     [基本工資]   [numeric](18,   2)   NULL   ,     
    10.     [獎金]   [numeric](18,   2)   NULL   ,     
    11.     [合計]   [numeric](19,   2)   NULL   ,     
    12.     CONSTRAINT   [PK_data2]   PRIMARY   KEY     CLUSTERED       
    13.     (     
    14.       [人員編號]     
    15.     )     ON   [PRIMARY]       
    16.   )   ON   [PRIMARY]     
    17.   GO     
    18.       
    19.   insert   data2   select   'a1',1.00,11.00,111.00     
    20.   insert   data2   select   'a2',2.00,22.00,222.00     
    21.   insert   data2   select   'a3',3.00,33.00,333.00     
    22.   insert   data2   select   'a100',100.00,100.00,100.00     
    23.       
    24.   go     
    25.   drop       PROCEDURE   AVB_IniTable     
    26.   go     
    27.   /*    
    28.   author:nyb    
    29.   time     :2005/04/22    
    30.   fixtime :    
    31.   aim       :轉置行和列    
    32.   input   :@TableNane    
    33.   執行:    
    34.   EXECUTE   AVB_IniTable   'data2'    
    35.   */     
    36.       
    37.   Create       PROCEDURE   AVB_IniTable     
    38.   @TableNane   varchar(128)     
    39.       
    40.   AS     
    41.   DECLARE   @string   VARCHAR(8000)     
    42.   --1   創建View     
    43.   IF   EXISTS(   select     *     from   sysobjects   where   xtype='V'and   name   ='V_Temp'   )     
    44.   Begin     
    45.   Drop   view     V_Temp       
    46.   End       
    47.       
    48.   SELECT   @string   =   '   Create   view   V_Temp   as     select   *     from   '   +   @TableNane       
    49.   EXECUTE   (@string)     
    50.       
    51.   IF   EXISTS(   select     *     from   sysobjects   where   xtype='U'and   name   ='zzTemp'   )     
    52.   Begin     
    53.   Drop   table     zzTemp       
    54.   End       
    55.       
    56.       
    57.   DECLARE   @ColumnName   VARCHAR(200)     
    58.   DECLARE   @ColumnStr   VARCHAR(5000)     
    59.   select   @ColumnStr=   ''     
    60.   select   @ColumnStr=@ColumnStr   +   quotename(rtrim(人員編號))   +'float   NULL,'   from   V_Temp       
    61.   print   @ColumnStr     
    62.       
    63.   SET   @ColumnStr   =   left(@ColumnStr,len(@ColumnStr)-1)     
    64.   SELECT   @string   =   'CREATE   TABLE   zzTemp   (列名   varchar(50)   NULL,'   +     @ColumnStr   +   ')   ON   [PRIMARY]'     
    65.   print   @string     
    66.   EXECUTE   (@string)     
    67.       
    68.   --2插入記錄     
    69.   DECLARE   Column_cur     SCROLL   CURSOR   FOR     
    70.   SELECT   name   FROM   syscolumns   WHERE   ID=object_id(@TableNane)   and   name   <>'人員編號'     
    71.   OPEN     Column_cur       
    72.   FETCH   FIRST   FROM     Column_cur   into   @ColumnName     
    73.   WHILE   (@@fetch_status<>-1)     
    74.   BEGIN     
    75.   select   @ColumnStr=   ''     
    76.   if   @ColumnName   =   '基本工資'     
    77.   select   @ColumnStr=   @ColumnStr   +   ''''   +   convert(varchar(20),ISNULL(基本工資,0))   +   ''','   from   V_Temp         
    78.   else   if   @ColumnName   =   '獎金'     
    79.   select   @ColumnStr=   @ColumnStr   +   ''''   +   convert(varchar(20),ISNULL(獎金,0))   +   ''','   from   V_Temp         
    80.   else   if   @ColumnName   =   '合計'     
    81.   select   @ColumnStr=   @ColumnStr   +   ''''   +   convert(varchar(20),ISNULL(合計,0))   +   ''','   from   V_Temp         
    82.       
    83.     SET   @ColumnStr   =   left(@ColumnStr,len(@ColumnStr)-1)     
    84.     select   @string   =   'insert   into   zzTemp   values('''   +   @ColumnName   +   ''','   +     @ColumnStr   +')'     
    85.   execute(@string)     
    86.   FETCH   NEXT   FROM     Column_cur   into   @ColumnName     
    87.   END     
    88.   CLOSE   Column_cur     
    89.   DEALLOCATE   Column_cur     
    90.       
    91.       
    92.   go     
    93.   --察看結果     
    94.   select   *   from   data2     
    95.   select   *   from   zzTemp   

     

     

     =====================================================================

    1. if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[dbo].[p_zj]')   and   OBJECTPROPERTY(id,   N'IsProcedure')   =   1)     
    2.   drop   procedure   [dbo].[p_zj]     
    3.   GO     
    4.       
    5.   /*--行列互換的通用存儲過程    
    6.      
    7.   將指定的表,按指定的字段進行行列互換    
    8.      
    9.   --鄒建   2004.04--*/     
    10.       
    11.   /*--使用示例    
    12.      
    13.   --測試數據    
    14.   create   table   表(類別   varchar(10),男性   decimal(20,1),女性   decimal(20,1))    
    15.   insert   表   select   '小說',38.0,59.2    
    16.   union   all   select   '散文',18.9,30.6    
    17.   union   all   select   '哲學',16.2,10.2    
    18.      
    19.   /*--要求轉換結果    
    20.   性別       小說         散文         哲學            
    21.   ----   -----   -----   -----      
    22.   男性       38.0     18.9     16.2    
    23.   女性       59.2     30.6     10.2    
    24.      
    25.   (所影響的行數爲   2   行)    
    26.   --*/     
    27.       
    28.   --調用存儲過程     
    29.   exec   p_zj   '表','類別','性別'     
    30.       
    31.   --刪除測試     
    32.   drop   table   表     
    33.   --*/     
    34.   create   proc   p_zj     
    35.   @tbname   sysname, --要處理的表名     
    36.   @fdname   sysname, --做爲轉換的列名     
    37.   @new_fdname   sysname='' --爲轉換後的列指定列名     
    38.   as     
    39.   declare   @s1   varchar(8000),@s2   varchar(8000)     
    40.   ,@s3   varchar(8000),@s4   varchar(8000),@s5   varchar(8000)     
    41.   ,@i   varchar(10)     
    42.   select   @s1='',@s2='',@s3='',@s4='',@s5='',@i='0'     
    43.   select   @s1=@s1+',@'+@i+'   varchar(8000)'     
    44.   ,@s2=@s2+',@'+@i+'='''+case   isnull(@new_fdname,'')   when   ''   then   ''     
    45.   else   @new_fdname+'='   end+''''''+name+''''''''     
    46.   ,@s3=@s3+'     
    47.   select   @'+@i+'=@'+@i+'+'',[''+cast(['+@fdname+']   as   varchar)+'']=''''''+replace(['+name+'],'''','''''''')+''''''''   from   ['+@tbname+']'     
    48.   ,@s4=@s4+',@'+@i+'=''select   ''+@'+@i     
    49.   ,@s5=@s5+'+''   union   all   ''+@'+@i     
    50.   ,@i=cast(@i   as   int)+1     
    51.   from   syscolumns       
    52.   where   object_id(@tbname)=id   and   name<>@fdname     
    53.   order   by   colid     
    54.       
    55.   select   @s1=substring(@s1,2,8000)     
    56.   ,@s2=substring(@s2,2,8000)     
    57.   ,@s4=substring(@s4,2,8000)     
    58.   ,@s5=substring(@s5,16,8000)     
    59.       
    60.   exec('declare   '+@s1+'     
    61.   select   '+@s2+@s3+'     
    62.   select   '+@s4+'     
    63.   exec('+@s5+')')     
    64.   go  

     

     

    Oracle's:

     

     

    1. 最近公司項目涉及到統計報表,有關交叉報表部分差不多都有行列轉換需求,根據個人開發中的需求,總結了一些例子  
    2.   
    3. 1.創建表  
    4.   
    5. create table T1  
    6. (  
    7.   PRODUCTID VARCHAR2(100),  
    8.   NUM       NUMBER  
    9. )  
    10. ;  
    11.   
    12. 2.插入測試數據  
    13.   
    14. insert into T1 (PRODUCTID, NUM)  
    15. values ('1'3);  
    16. insert into T1 (PRODUCTID, NUM)  
    17. values ('2'12);  
    18. insert into T1 (PRODUCTID, NUM)  
    19. values ('3'24);  
    20. insert into T1 (PRODUCTID, NUM)  
    21. values ('4'11);  
    22. insert into T1 (PRODUCTID, NUM)  
    23. values ('5'51);  
    24. insert into T1 (PRODUCTID, NUM)  
    25. values ('6'511);  
    26. commit;  
    27.   
    28. 3.編寫轉換函數  
    29.   
    30. CREATE OR REPLACE FUNCTION fn_rs_1  
    31.     RETURN pkg_getrecord.myrctype  
    32. IS  
    33.     s VARCHAR2 (4000);  
    34.     CURSOR c1 IS  
    35.     SELECT ',sum(case when productid!='|| productid || ' then num else 0 end)' || ' "產品' || productid|| '"' c2  
    36.     FROM t1  
    37.     group by productid;  
    38.     r1 c1%ROWTYPE;  
    39.     list_cursor pkg_getrecord.myrctype;  
    40. BEGIN  
    41.     s := 'select  1 ';  
    42.     OPEN c1;  
    43.     LOOP  
    44.         FETCH c1 INTO r1;  
    45.         EXIT WHEN c1%NOTFOUND;  
    46.         s := s || r1.c2;  
    47.     END LOOP;  
    48.     CLOSE c1;  
    49.     s := s || ' from t1 g ';  
    50.     dbms_output.put_line(s);  
    51.     OPEN list_cursor FOR s;  
    52.     RETURN list_cursor;  
    53. END fn_rs_1;  
    54.   
    55. 4.java測試代碼  
    56.   
    57. public class Test {  
    58.  private String db_url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";  
    59.  private String db_username = "test";  
    60.  private String db_passwd = "test";  
    61.   
    62.  /** 
    63.   * @param args 
    64.   */  
    65.  public static void main(String[] args) {  
    66.   Test test=new Test();  
    67.   try {  
    68.    test.exec();  
    69.   } catch (SQLException e) {  
    70.    e.printStackTrace();  
    71.   }  
    72.  }  
    73.   
    74.  public void exec() throws SQLException {  
    75.   Connection conn = getConnection();  
    76.   if(conn==null){  
    77.    throw new SQLException("database not connectioned");  
    78.   }  
    79.   CallableStatement cstmt = conn.prepareCall("{?=call fn_rs_1}");  
    80.   cstmt.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);  
    81.   cstmt.execute();  
    82.   ResultSet rs=(ResultSet)cstmt.getObject(1);  
    83.   if(rs.next()){  
    84.    for(int j=1;j<=rs.getMetaData().getColumnCount();j++){  
    85.     System.out.print(rs.getMetaData().getColumnName(j)+"/t");  
    86.    }  
    87.   }  
    88.   System.out.println("");  
    89.   cstmt.execute();  
    90.   rs=(ResultSet)cstmt.getObject(1);  
    91.   while(rs.next()){  
    92.    System.out.print(rs.getString(1)+"/t");  
    93.    System.out.print(rs.getString(2)+"/t");  
    94.    System.out.print(rs.getString(3)+"/t");  
    95.    System.out.print(rs.getString(4)+"/t");  
    96.    System.out.print(rs.getString(5)+"/t");  
    97.    System.out.print(rs.getString(6)+"/t");  
    98.    System.out.print(rs.getString(7)+"/t");  
    99.   }  
    100.   cstmt.close();  
    101.  }  
    102.   
    103.  protected Connection getConnection() {  
    104.   try {  
    105.    Class.forName("oracle.jdbc.driver.OracleDriver");  
    106.    return DriverManager.getConnection(db_url, db_username, db_passwd);  
    107.   } catch (ClassNotFoundException e) {  
    108.    e.printStackTrace();  
    109.   } catch (SQLException e) {  
    110.    e.printStackTrace();  
    111.   }  
    112.   return null;  
    113.  }  
    114.   
    115. }  
    116.   
    117.   
    118. 本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/jianping_shen/archive/2009/04/01/4041169.aspx 

發佈了434 篇原創文章 · 獲贊 93 · 訪問量 154萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章