0

複数のアカウント番号が異なる ID (DR_NAME) に関連付けられているテーブルがあります。各アカウントは 0 個のアカウントを持つことも、16 個のアカウントを持つこともできます。UNPIVOT は機能すると思いますが、私はこれをサポートしていない Oracle 10g を使用しています。

DR_NAME   ACCT1   ACCT2   ACCT3   ACC4  
======================================
SMITH     1234
JONES     5678    2541    2547
MARK      NULL    
WARD      8754    6547

1 行に 1 つのアカウント番号のみを使用して、名前ごとに新しい行を表示したい

DR_NAME   ACCT
==============
SMITH     1234
JONES     5678
JONES     2541
JONES     2547
MARK      NULL
WARD      8754
WARD      6547
4

3 に答える 3

1

私が知っている最も効率的な方法は、いくつかのロジックでクロス結合を行うことです。

select *
from (select t.dr_name,
             (case when n.n = 1 then acct1
                   when n.n = 2 then acct2
                   when n.n = 3 then acct3
                   when n.n = 4 then acct4
              end) as acct
      from t cross join
           (select 1 as n from dual union all
            select 2 from dual union all
            select 3 from dual union all
            select 4 from dual
           ) n
     ) s
where acct is not null

通常のunion allアプローチでは、サブクエリごとにテーブルを 1 回スキャンします。この方法では、通常、テーブルを 1 回スキャンします。

于 2013-05-02T14:13:27.180 に答える
1

Oracle 10g にはUNPIVOT関数がありませんが、UNION ALLクエリを使用して列を行にアンピボットできます。

select t1.DR_NAME, d.Acct
from yourtable t1
left join
(
  select DR_NAME, ACCT1 as Acct
  from yourtable
  where acct1 is not null
  union all
  select DR_NAME, ACCT2 as Acct
  from yourtable
  where acct2 is not null
  union all
  select DR_NAME, ACCT3 as Acct
  from yourtable
  where acct3 is not null
  union all
  select DR_NAME, ACCT4 as Acct
  from yourtable
  where acct4 is not null
) d
  on t1.DR_NAME = d.DR_NAME;

SQL Fiddle with Demoを参照してください。

このクエリは、UNION ALLを使用して列を行に変換します。where値を削除する句を含めましたnull。そうしないと、acct 値が null であるアカウントごとに複数の行が取得されます。値を除外すると、最終結果に必要なnull値が表示されなくなります。dr_name = Mark値のみを持つ行を含めるためにnull、結合をテーブルに再度追加しました。

于 2013-05-02T14:08:11.037 に答える