Способ представления данных в Oracle - PullRequest
0 голосов
/ 03 сентября 2018

Мне нужен способ, чтобы избежать дублирования данных из соединения оракула, представлять только один раз каждое значение, у меня есть этот сценарий.

Первая таблица содержит общую информацию о человеке.

+-----------+-------+-------------+
| ID        | Name  | Birtday_date|
+-----------+-------+-------------+
| 1         | Byron | 12/10/1998  |
| 2         | Peter | 01/11/1973  |
| 4         | Jose  | 05/02/2008  |
+-----------+-------+-------------+

Вторая таблица содержит информационные данные о телефоне людей из первой таблицы.

+-------+----------+----------+----------+
| ID    |ID_Person |CELL_TYPE | NUMBER   |
+-------+- --------+----------+----------+
| 1221  | 1        | 3        | 099141021|
| 2221  | 1        | 2        | 099091925|
| 3222  | 1        | 1        | 098041013|
| 4321  | 2        | 1        | 088043153|
| 4561  | 2        | 2        | 090044313|
| 5678  | 4        | 1        | 092049013|
| 8990  | 4        | 2        | 098090233|
+----- -+----------+----------+----------+

Третья таблица содержит информационные данные об электронной почте людей из первой таблицы.

+------+----------+----------+---------------+
| ID   |ID_Person |EMAIL_TYPE| Email         |
+------+- --------+----------+---------------+
| 221  | 1        | AC1      |jdoe@aol.com   |
| 222  | 1        | AB2      |jdoe1@aol.com  |
| 421  | 2        | AC1      |xx12@yahoo.com |
| 451  | 2        | AB2      |dsdsa@gmail.com|
| 578  | 4        | AC1      |sasaw1@sdas.com|
| 899  | 4        | AB2      |cvcvsd@wew.es  |
| 899  | 4        | AB2      |cvsd@www.es    |
+------+----------+----------+---------------+

Если вы используете joins, результат будет примерно таким.

+-----+-------+-------------+----------+----------+----------+----------------+
| ID  | Name  | Birtday_date| CELL_TYPE|  NUMBER  |EMAIL_TYPE|EMAIL           |
+-----+-------+-------------+----------+----------+----------+----------------+
| 1   | Byron | 12/10/1998  | 3        | 099141021|AC1       |jdoe@aol.com    |   
| 1   | Byron | 12/10/1998  | 3        | 099141021|AB2       |jdoe1@aol.com   |  
| 1   | Byron | 12/10/1998  | 2        | 099091925|AC1       |jdoe@aol.com    |   
| 1   | Byron | 12/10/1998  | 2        | 099091925|AB2       |jdoe1@aol.com   | 
| 1   | Byron | 12/10/1998  | 1        | 098041013|AC1       |jdoe@aol.com    |   
| 1   | Byron | 12/10/1998  | 1        | 098041013|AB2       |jdoe1@aol.com   | 
| 2   | Peter | 01/11/1973  | 1        | 088043153|AC1       |xx12@yahoo.com  |
| 2   | Peter | 01/11/1973  | 1        | 088043153|AC1       |dsdsa@gmail.com |
| 2   | Peter | 01/11/1973  | 2        | 090044313|AC1       |xx12@yahoo.com  |
| 2   | Peter | 01/11/1973  | 2        | 090044313|AC1       |dsdsa@gmail.com |
| 4   | Jose  | 05/02/2008  | 1        | 092049013|AC1       |sasaw1@sdas.com |
| 4   | Jose  | 05/02/2008  | 1        | 092049013|AC1       |cvcvsd@wew.     |
| 4   | Jose  | 05/02/2008  | 1        | 092049013|AC1       |cvsd@www.es     |
| 4   | Jose  | 05/02/2008  | 2        | 098090233|AB2       |sasaw1@sdas.com |
| 4   | Jose  | 05/02/2008  | 2        | 098090233|AB2       |cvcvsd@wew.es   |
| 4   | Jose  | 05/02/2008  | 2        | 098090233|AB2       |cvsd@www.es     |    
+-----+-------+-------------+----------+----------+----------+----------------+

Результат, который я ожидал, примерно такой.

+-----+-------+-------------+----------+----------+----------+----------------+
| ID  | Name  | Birtday_date| CELL_TYPE|  NUMBER  |EMAIL_TYPE|EMAIL           |
+-----+-------+-------------+----------+----------+----------+----------------+
| 1   | Byron | 12/10/1998  | 3        | 099141021|AC1       |jdoe@aol.com    |   
| 1   | Byron | 12/10/1998  | 2        | 099091925|AB2       |jdoe1@aol.com   | 
| 1   | Byron | 12/10/1998  | 1        | 099091925|          |                | 
| 2   | Peter | 01/11/1973  | 1        | 088043153|AC1       |xx12@yahoo.com  |
| 2   | Peter | 01/11/1973  | 2        | 090044313|AB2       |dsdsa@gmail.com |
| 4   | Jose  | 05/02/2008  | 1        | 092049013|AC1       |sasaw1@sdas.com |
| 4   | Jose  | 05/02/2008  | 2        | 098090233|AB2       |cvcvsd@wew.es   |
| 4   | Jose  | 05/02/2008  |          |          |AB2       |cvsd@www.es     |
+-----+-------+-------------+----------+----------+----------+----------------+

Это способ, которым мне нужно представить данные.

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

В качестве дополнения к ответу APC, вы можете, предполагая, что столбец id_person в таблицах телефонов и электронных писем является внешним ключом столбца id в таблице person, сначала выполнить полное внешнее объединение в таблице телефонов и электронных писем, перед тем, как присоединить это обратно к таблице лиц, например:

with t as ( select x.*
                   , row_number() over (partition by x.id_person order by x.id) as rn
            from phones x ) 
   , e as ( select x.*
                        , row_number() over (partition by x.id_person order by x.id) as rn
                from emails x )
   , et as (
     select coalesce (e.id_person, t.id_person) id_person,
            t.cell_type,
            t.cell,
            e.email_type,
            e.email,
            coalesce(e.rn, t.rn) rn
     from   t
     full outer join e on t.id_person = e.id_person and t.rn = e.rn
     )
select p.id
       , p.name
       , et.cell_type
       , et.cell
       , et.email_type
       , et.email
from person p 
     inner join et on et.id_person = p.id
order by p.id, et.rn;

SQLfiddle: http://sqlfiddle.com/#!4/c4c0c/4

На вашем месте я бы проверил этот ответ и ответ APC, чтобы выяснить, какой из них лучше всего подходит для ваших фактических данных.

0 голосов
/ 03 сентября 2018

То, что вы пытаетесь достичь, это:

select p.id
       , p.name
       , cursor ( select t.cell_type, t.cell
                from phones  t
            where t.id_person = p.id
            order by t.id    )
       , cursor ( select e.email_type, e.email
                from emails  e
            where e.id_person = p.id
            order by e.id    )
from person p 
;

Загвоздка в том, способен ли используемый вами клиент отобразить вложенный курсор . В моих экспериментах выделялись и SQL Fiddle, и Oracle LiveSQL (хотя интересно, что SQL Fiddle был более изящным, чем LiveSQL).

Однако, если вам нужно решение на чистом SQL, которое будет работать на любом клиенте, вот оно:

with t as ( 
       select x.*
              , row_number() over (partition by x.id_person order by x.id) as rn
       from phones x ) 
   , e as ( 
       select x.*
              , row_number() over (partition by x.id_person order by x.id) as rn
       from emails x )
   , nos as (
       select rn from t 
       union select rn from e 
     )
select p.id
       , p.name
       , t.cell_type
       , t.cell
       , e.email_type
       , e.email
from person p 
     cross join nos
     left outer join t
            on t.id_person = p.id
            and t.rn = nos.rn
     left outer join  e
            on e.id_person = p.id
            and e.rn = nos.rn
where e.rn is not null 
or t.rn is not null            
order by p.id, nos.rn
;

Генерирует номера строк для подзапросов EMAILS и PHONES. Затем он генерирует список номеров строк, который применяется к результатам PERSON, и предоставляет фрейм, на котором мы можем ВНЕШНИЙ ВСТУПИТЬ результаты из подзапросов.

Вот демонстрационная программа SQL Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...