0

JOINを使用してOracle 10gで行を列に変換したい。DECODE または XMLAGG 関数を使用したくありません。私のテーブル構造は次のとおりです。

GROUP_ID    ENTITYID    GROUP_ENTITYID
1           A997        A995
2           A997        A993
3           A997        A990
4           A988        A987
5           A988        A982
6           A988        A980
7           A979        A975
8           A979        A974
9           A979        A973

次の形式でデータを取得したい:

ENTITYID    GROUP_ENTITYID

A979    A979,A975,A974,A973
A988    A988,A987,A982,A980
A997    A997,A995,A993,A990

どうすればよいかアドバイスをいただけますか?

前もって感謝します。

4

1 に答える 1

1

Tim Hall は、Oracle で使用できるさまざまな文字列集約手法の標準的なリストを持っています。

結合を使用してデータを結合することは、実用的でも効率的でもありません。EntityIDそれが正確に 3 つの他の値にマップされることがわかっている場合Group_EntityIDは、結合を使用できます。

SELECT a.entity_id, 
       a.entity_id || ','  ||
         a.group_entityID || ',' ||
         b.group_entityID || ',' ||
         c.group_entityID
  FROM table_name a,
       table_name b,
       table_name c
 WHERE a.entityID = b.entityID
   AND a.entityID = c.entityID
   AND a.group_entityID > b.group_entityID
   AND b.group_entityID > c.group_entityID

Group_EntityIDしかし、特定の変更に関連付けられた値の数が変化した場合、そのアプローチは特に効率的でも柔軟でもありませんEntityID

私は通常、ユーザー定義の集計関数 (Tim のリストのオプションの 1 つ) を作成し、次のようなことを行うことを好みます。

SELECT entityID, entityID || ',' || string_agg( group_entity_id )
  FROM table_name
 GROUP BY entityID;

追加のオブジェクトや関数を作成せずに実行したい場合はSYS_CONNECT_BY_PATH、Tim のサイトのアプローチを使用できます。

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 1 group_id, 'A997' entityID, 'A995' group_entityID from dual union all
  3    select 2, 'A997', 'A993' from dual union all
  4    select 3, 'A997', 'A990' from dual union all
  5    select 4, 'A998', 'A987' from dual union all
  6    select 5, 'A998', 'A982' from dual union all
  7    select 6, 'A998', 'A980' from dual union all
  8    select 7, 'A979', 'A975' from dual union all
  9    select 8, 'A979', 'A974' from dual union all
 10    select 9, 'A979', 'A973' from dual
 11  )
 12  select entityID,
 13         entityID || ',' ||
 14           ltrim( max( sys_connect_by_path( group_entityID, ','))
 15                     keep(dense_rank last order by group_id),
 16                  ',') group_entityID
 17    from (select group_id,
 18                 entityID,
 19                 group_entityID,
 20                 row_number() over (partition by entityID
 21                                        order by group_id) curr,
 22                 row_number() over (partition by entityID
 23                                        order by group_id) - 1 prev
 24            from x)
 25   group by entityID
 26  connect by prev = PRIOR curr
 27      and entityID = PRIOR entityID
 28*  start with curr = 1
SQL> /

ENTI GROUP_ENTITYID
---- ------------------------------
A979 A979,A975,A974,A973
A997 A997,A995,A993,A990
A998 A998,A987,A982,A980
于 2012-04-04T14:38:19.723 に答える