3

Person (person_id, name) と別のテーブルContacts (person_id, phone_type, phone_no)という 2 つのテーブルがあります。

人
-----------------
person_id 名
-----------------
P1 Abc
P2 エクシーズ
連絡先
--------------------------------
person_id phone_type phone_no
--------------------------------
P1 phone1 12345
P1 phone2 23455
P2 phone1 67897
P2 phone3 89786

次のようなビュー v_pc を作成する必要があります

v_pc
person_id 名前 phone1 phone2 phone3
--------------------------------------
P1 Abc 12345 23455  
P2 エクシーズ 67897 89786

つまり、連絡先テーブルの行がピボットされて、ビューの列が形成されます (列の数は、'phone_types' 列の個別の値に基づいて可変になります)。

連絡先テーブルをピボットする方法はありますが、次のような動的ピボットイン句を使用できますか

選択する *
 から (
    選択する
        person_idd、
        phone_type、
        電話番号
    連絡先から
 ) PIVOT (MAX(phone_no) FOR phone_type IN ('phone1','phone2','phone3'))

また、ピボットでXML句を使用しようとしたので、動的なピボットイン句を使用します。つまり、XMLで結果を抽出し、XMLTABLEを使用して列を再作成します。しかし、私は望ましい結果に到達することができません。

4

2 に答える 2

2

動的 SQL を使用できます (これは、SYS_REFCURSOR 型のバインド変数 v_cur があることを前提としています)。

declare
  v_sql varchar2(32000);
  v_phonetypes varchar2(32000);
begin
  -- base SQL statement
  v_sql := 'SELECT *
    FROM (
      SELECT
        person_id,
        phone_type,
        phone_no
      FROM contacts
    ) PIVOT (MAX(phone_no) FOR phone_type IN (';

  -- comma-separated list of phone types
  select 
    listagg('''' || phone_type || '''', ',') within group (order by phone_type) 
  into v_phonetypes 
  from (select distinct phone_type from contacts);

  v_sql := v_sql || v_phonetypes || '))';
  dbms_output.put_line(v_sql);
  -- execute query 
  open :v_cur for v_sql;
end;

LISTAGG() には 11gR2 が必要ですが、PIVOT を使用しているので、とにかく使用していると思います。

于 2012-08-22T10:00:16.373 に答える
0

動的 SQL を使用してビューを作成してみませんか? Frank が上記の PIVOT クエリを作成したのと同じ方法で CREATE ステートメントを設計するだけです。次に、最初に CREATE ステートメントを実行し、後で PIVOT クエリを実行します。

于 2013-02-06T07:39:18.933 に答える