1

複数の列に変数が入力された Oracle テーブルがあり、多数の可能な変数があります。以下の例はすべてを網羅しているわけではありません。

ID  Col1  Col2  Col3 
--------------------
1   A     B
2   B     A     D
3   B     C
4   C     B     
5   B     B
6   E     D   
7   B     A     C

各行の変数を並べ替えるクエリを作成する必要があります。

ID  Col1  Col2  Col3 
--------------------
1   A     B
2   A     B     D
3   B     C
4   B     C     
5   B     B
6   D     E   
7   A     B     C

現実世界の問題には、最大 40 の異なる変数 (それぞれ最大 4 文字の長さ) と数百万のレコードを持つ 20 の列があるため、エレガントなソリューションを探しています。

4

1 に答える 1

1

以下は、Oracle 10g以降のバリアントです。元のデータセットには多数の行があるため、完全な結果セットの上にグループ化と分析関数を含むソリューションを回避しようとします。

この例のベース テーブル:

create table tab1 (
  ID   number,
  col1 varchar2(4), 
  col2 varchar2(4), 
  col3 varchar2(4), 
  col4 varchar2(4) 
)

ID最初に、ソートされたコレクションごとにすべての列を収集します。

select
  tab1.ID,
  cast( multiset(
    select 
      decode(level,
        1, tab1.col1,
        2, tab1.col2,
        3, tab1.col3,
        4, tab1.col4,
        null
      )       
    from dual 
    connect by level <= 4
    order by 
      decode(level,
        1, tab1.col1,
        2, tab1.col2,
        3, tab1.col3,
        4, tab1.col4,
        null
      ) 
      nulls last          
  ) as sys.ODCIVarchar2List) sorted_values
from tab1;

このようなデータセットを使用すると、指定された順序を維持しながら、値をデコードして列に戻すことができます。

select
  ID,
  (
    select column_value 
    from table(data_list.sorted_values)
    where rownum = 1
  ) as col1,
  (
    select max(decode(rownum, 2, column_value, null))
    from table(data_list.sorted_values)
  ) as col2,
  (
    select max(decode(rownum, 3, column_value, null))
    from table(data_list.sorted_values)
  ) as col3,
  (
    select max(decode(rownum, 4, column_value, null))
    from table(data_list.sorted_values)
  ) as col4
from (
  select
    rownum,  -- this needed as workaround for Oracle bug
    tab1.ID,
    cast( multiset(
      select 
        decode(level,
          1, tab1.col1,
          2, tab1.col2,
          3, tab1.col3,
          4, tab1.col4,
          null
        )       
      from dual 
      connect by level <= 4
      order by 
        decode(level,
          1, tab1.col1,
          2, tab1.col2,
          3, tab1.col3,
          4, tab1.col4,
          null
        ) 
        nulls last          
    ) as sys.ODCIVarchar2List) sorted_values
  from tab1
) 
  data_list

SQLFiddle test

この Oracle エラーの回避策として、rownuminner 句に存在する必要があることに注意してください。select

于 2013-09-26T17:31:56.523 に答える