【问题标题】:Excel aggregating functionExcel 汇总函数
【发布时间】:2012-12-19 03:07:56
【问题描述】:

我有一个带有列的 excel 文件,

C_IP
SESSION_ID
CS_USER_AGENT
CS_URI_STEM
CS_URI_QUERY
WEB_LINK

由于 Oracle (11g) 中允许的字符串大小的限制,我无法汇总上述属性。我尝试使用用户定义的聚合函数。我想聚合“WEB_LINK”列,并按 C_IP 分组。是否可以在 Excel 中执行此操作?

我尝试使用的 SQL 查询是,

CREATE TABLE WEBLOG_AGG AS
SELECT C_IP,
tab_to_string(CAST(COLLECT(WEB_LINK) AS T_VARCHAR2_TAB)) AS WEBLINKS
FROM WEBLOG_SESSION
GROUP BY C_IP;

【问题讨论】:

    标签: sql excel oracle11g


    【解决方案1】:

    我想执行连接到clob 比编写 VBA 代码更容易。

    15:34:36 SYSTEM@dwal> create table t1 ( group_col number, value varchar2(1 byte) );
    
    Table created.
    
    Elapsed: 00:00:00.10
    15:34:38 SYSTEM@dwal> insert into t1
    15:35:34   2  select 1, decode(mod(rownum,5), 0,0,1) from dual connect by rownum <= 4001
    15:36:20   3  union all
    15:36:22   4  select 2, decode(mod(rownum,5), 0,0,1) from dual connect by rownum <= 4001
    15:36:27   5  ;
    
    8002 rows created.
    
    Elapsed: 00:00:00.05
    15:36:28 SYSTEM@dwal> commit;
    
    Commit complete.
    
    Elapsed: 00:00:00.02
    15:36:31 SYSTEM@dwal> create type t_varchar2_tab is table of varchar2(1);
    15:37:11   2  /
    
    Type created.
    
    Elapsed: 00:00:00.50
    15:38:15 SYSTEM@dwal> ed
    Wrote file S:\tools\buffer.sql
    
      1  create function tab_to_str(tab in t_varchar2_tab) return clob
      2  as
      3    result clob;
      4  begin
      5    for i in tab.first .. tab.last loop
      6      result := result || tab(i);
      7    end loop;
      8    return result;
      9* end;
    15:38:46 SYSTEM@dwal> /
    
    Function created.
    
    Elapsed: 00:00:00.19
    15:46:01 SYSTEM@dwal> select group_col
    15:46:04   2  ,length(tab_to_str(cast(collect(value) as t_varchar2_tab))) len
    15:46:10   3  ,substr(tab_to_str(cast(collect(value) as t_varchar2_tab)), 1, 20) val
    15:46:12   4  from t1 group by group_col;
    
     GROUP_COL    LEN VAL
    ---------- ------ --------------------
             1   4001 11011110111101111011
             2   4001 11011110111101111011
    
    Elapsed: 00:00:01.13
    

    【讨论】:

      【解决方案2】:

      直到我在这个问题中看到它之前,我什至没有听说过 COLLECT() 函数,但它看起来非常有用。根据我所阅读的内容,我认为以下内容应该在聚合 web_link 列时将您的 Excel 工作表减少为唯一行。它不会即时执行(这可能是您正在寻找的),但是一旦数据存在,您就可以在整个工作表上运行它。

      Public Type Entry
          C_IP As String
          rowNum As Integer
      End Type
      
      Public entryList() As Entry
      
      Sub AggregateRows()
      
          Dim lastRow As Integer
          Dim i As Integer
          Dim webLinks As String
          Dim entryItem As Entry
          Const C_IPColumn As Integer = 1         ' This is the column number of the C_IP column
          Const WEB_LINKColumn As Integer = 6     ' This is the column number of the WEB_LINK column
      
          ReDim entryList(0)
      
          ' Get the last used row on the sheet
      
          lastRow = ActiveSheet.Cells.Find("*", SearchOrder:=xlByRows, LookIn:=xlValues, SearchDirection:=xlPrevious).Row
      
          ' Loop through all of the rows
      
          For i = 1 To lastRow
      
              ' See if we've already encountered the C_IP in this row
      
              entryItem = GetEntry(ActiveSheet.Cells(i, C_IPColumn).Value)
      
              If Not entryItem.C_IP = "" Then
      
                  ' We have, so add the current web link to the list for the row associated with this C_IP
      
                  webLinks = ActiveSheet.Cells(entryItem.rowNum, WEB_LINKColumn).Value
                  webLinks = webLinks & ", " & ActiveSheet.Cells(i, WEB_LINKColumn).Value
                  ActiveSheet.Cells(entryItem.rowNum, WEB_LINKColumn).Value = webLinks
      
                  ' Now remove this row (since it has been grouped with row with the same C_IP)
      
                  ActiveSheet.Rows(i).Delete
      
                  ' Decrement our counters by 1 since we have 1 fewer rows (assuming we're not on the last row already)
      
                  If Not i = lastRow Then
      
                      i = i - 1
                      lastRow = lastRow - 1
      
                  End If
      
              Else
      
                  ' We've not encountered this C_IP yet, so add it to the list
      
                  ReDim Preserve entryList(UBound(entryList) + 1)
                  entryList(UBound(entryList)).C_IP = ActiveSheet.Cells(i, C_IPColumn).Value
                  entryList(UBound(entryList)).rowNum = i
      
              End If
      
          Next i
      
      End Sub
      
      ' Returns the Entry matching the passed-in C_IP
      Function GetEntry(C_IP As String) As Entry
      
          Dim i As Integer
      
          ' Loop through all stored entries and return the first whose C_IP matches that passed in
      
          For i = 0 To UBound(entryList)
              If entryList(i).C_IP = C_IP Then
                  GetEntry = entryList(i)
              End If
          Next i
      
      End Function
      
      ' A quick and dirty way to get an empty Entry
      Function GetEmptyEntry() As Entry
      
      End Function
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多