7

列を含む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;
4

2 に答える 2

3

clobVBA コードを記述するよりも連結を実行する方が簡単だと思います。

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
于 2012-12-19T07:48:31.067 に答える
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
于 2012-12-19T07:22:03.430 に答える