Выбор одного SQL для таблиц отношений «один ко многим» с использованием разделителя в столбце - Oracle - PullRequest
0 голосов
/ 17 марта 2011

У меня есть две таблицы с отношением один-ко-многим.

Таблица Person:

Id_person    Name
-----------------------
1            Jack Black
2            Joe White

Настольный телефон:

Id_telephone Id_person Number     Type
----------------------------------------
5            1         333222111  Mobile
6            1         444333222  Fax
7            2         555444333  Mobile

Желаемый результат оператора SQL SELECT:

Name        Telephone_Numbers
---------------------------------------------
Jack Black  Mobile: 333222111, Fax: 444333222
Joe White   Mobile: 555444333

Я нашел много ответов на этот вопрос, но, связанных с SQL Server, я понятия не имею, как этого добиться с помощью Oracle Database 10g. Мне нужно заполнить Gridview в ASP.NET с таким результатом, поэтому я хочу использовать этот оператор SELECT с OracleCommand и ExecuteQuery ().

Спасибо за любые подсказки.

Ответы [ 5 ]

2 голосов
/ 17 марта 2011

в 11gR2 вы можете использовать listAgg

with person as
(
select 1   id_person, 'Jack Black' FullName from dual
union all
select 2   id_person, 'Joe White' FullName  from dual
)
, telephone as
(
select 5  id_telephone ,          1    Id_person,     333222111 phone_Number ,  'Mobile' phone_type from dual
union all
select 6  id_telephone ,          1    Id_person,     444333222 phone_Number ,  'Fax' phone_type from dual
union all
select 7  id_telephone ,          2    Id_person,     555444333 phone_Number ,  'Mobile' phone_type from dual
)
select person.FullName  
      ,listagg(telephone.phone_type || ': ' || telephone.phone_number , ', ') within group (order by person.FullName ) personToPhone

  from person 
       inner join
       telephone
         on person.id_person = telephone.id_person 
group by person.FullName ;


FULLNAME   PERSONTOPHONE                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
---------- -----------------------------------
Jack Black Fax: 444333222, Mobile: 333222111                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
Joe White  Mobile: 555444333

Посмотрите на этот вопрос для других подходов: список через запятую как результат оператора выбора в Oracle

РЕДАКТИРОВАТЬ

для 10g вы можете использовать XMLAgg

with person as
(
select 1   id_person, 'Jack Black' FullName from dual
union all
select 2   id_person, 'Joe White' FullName  from dual
)
, telephone as
(
select 5  id_telephone ,          1    Id_person,     333222111 phone_Number ,  'Mobile' phone_type from dual
union all
select 6  id_telephone ,          1    Id_person,     444333222 phone_Number ,  'Fax' phone_type from dual
union all
select 7  id_telephone ,          2    Id_person,     555444333 phone_Number ,  'Mobile' phone_type from dual
)
select person.FullName  
    ,RTRIM(XMLAGG(XMLELEMENT(e,telephone.phone_type || ': ' || telephone.phone_number || ',')).EXTRACT('//text()'),',') AS TelephoneToType
  from person 
       inner join
       telephone
         on person.id_person = telephone.id_person 
group by person.FullName ;

FULLNAME   TELEPHONETOTYPE                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
---------- ---------------------------------
Jack Black Mobile: 333222111,Fax: 444333222                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
Joe White  Mobile: 555444333 

(как это сделал Марк Бейкер в связанном вопросе SO)

1 голос
/ 24 марта 2011

Была такая же проблема некоторое время назад. Во всех ответах, которые я нашел, сказано, что используется listagg, но клиент использует 10g. Создайте эту функцию. Функция не моя найдена в сети.

create or replace
FUNCTION column_concat
(
    p_cursor sys_refcursor,
    p_del VARCHAR2 
)  RETURN VARCHAR2
IS
    l_value   VARCHAR2(32767);
    l_result  VARCHAR2(32767);
BEGIN
    LOOP
        FETCH p_cursor INTO l_value;
        EXIT WHEN p_cursor%notfound;
        IF l_result IS NOT NULL THEN
        l_result := l_result || p_del;
    END IF;
    l_result := l_result || l_value;
END LOOP;
RETURN l_result;
END column_concat;

используйте его в Select следующим образом:

select pers.name Names, column_concat(cursor(SELECT tel.type ||':' ||  tel.telnumber  FROM person per, telephone tel Where per.id_person = tel.id_person and tel.id_person = pers.id_person), ',' ) Telephone_Numbers from person pers;
1 голос
/ 17 марта 2011

Список возможных решений здесь

1 голос
/ 17 марта 2011
Select P.Name
    , 'Mobile: ' || Coalesce( Min( Case When T.Type = 'Mobile' Then Number End ),'' )
        + Coalesce( 'Fax: ' || Min( Case When T.Type = 'Fax' Then Number End ),'' )
From Person P
    Join Telephone T
        On T.Id_Person = P.Id_person
Group By P.Name
0 голосов
/ 17 марта 2011

Это должно работать для вас.Если вы используете 11g, есть встроенная агрегатная функция LISTAGG, которая проще:

with data
as
(  
    select
        p.id_person,
        p.name,
        t.type||': '||t.phone_number telephone_number,
        row_number() over (partition by p.id_person order by t.type) rn,
        count(*) over (partition by p.id_person) cnt
    from
        person p
        inner join telephone t
            on t.id_person = p.id_person 
)
select
    name,
    ltrim(sys_connect_by_path(telephone_number,', '),', ') telephone_number
from data
where rn = cnt
start with rn = 1
connect by prior id_person = id_person and prior rn = rn-1
order by id_person
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...