带变量列的SQL Pivot [英] SQL Pivot with variable columns

查看:96
本文介绍了带变量列的SQL Pivot的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个表,分别是 Person (人员),(person_id,姓名)和另一个表 Contacts (联系人)(person_id,phone_type,phone_no).

I have two tables say Person(person_id, name) and another table Contacts(person_id, phone_type, phone_no).

Person
-----------------
person_id    name
-----------------
P1           Abc 
P2           Xyz


Contacts
--------------------------------
person_id   phone_type  phone_no
--------------------------------
P1          phone1      12345
P1          phone2      23455
P2          phone1      67897
P2          phone3      89786

我需要创建一个外观类似的视图v_pc

I need to create a view v_pc which looks something like


v_pc
person_id  name phone1 phone2 phone3
-------------------------------------
P1         Abc  12345  23455  
P2         Xyz  67897         89786

即,联系人表的行被旋转以形成视图的列(列数将根据'phone_types'列的不同值而变化).

有什么办法可以枢纽化联系人表,但可以使用动态子句式,例如

i.e., rows of contacts table are pivot-ed to form columns for the view(number of columns will be variable based on distinct values of 'phone_types' column).

Is there any way I can Pivot the contacts table but use dynamic pivot-in-clause, something like


SELECT *
 FROM (
    SELECT
        person_idd,
        phone_type,
        phone_no
    FROM contacts
 ) PIVOT (MAX(phone_no) FOR phone_type IN ('phone1','phone2','phone3'))


我还尝试在枢轴中使用XML子句,因此请使用动态子句,即在XML中提取结果,然后使用XMLTABLE重新创建列.但是我无法达到预期的结果.


I also tried using XML clause in with pivot so use dynamic pivot-in-clause ,i.e., extracting result in XML and then recreating columns using XMLTABLE. But I am not able to reach the desired result.

推荐答案

您可以使用动态SQL(假设您具有类型为SYS_REFCURSOR的绑定变量v_cur):

You can use dynamic SQL (this assumes you have a bind variable v_cur of type SYS_REFCURSOR):

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,所以我想您还是在使用它.

LISTAGG() requires 11gR2, but since you're using PIVOT, I guess you're using it anyway.

这篇关于带变量列的SQL Pivot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆