SQL-запрос для объединения этих 3 таблиц для удаления ложных строк - OWNER, TYPE, PERSON - PullRequest
0 голосов
/ 29 апреля 2018

У меня возникли проблемы с присоединением к этим 3 таблицам.

Table1
OWNER     TYPE
O1        T1
O1        T2
O2        T1

Table2
OWNER     PERSON
O1        P1
O1        P2
O2        P1

Table3
TYPE     PERSON
T1       P1
T2       P2
T1       P2

Я хочу объединить все 3 таблицы, чтобы мой вывод был:

FinalTable
OWNER     TYPE     PERSON
O1        T1       P1
O1        T2       P2
O2        T1       P2
O1        T1       P2

Я в основном демонстрирую, как 5NF удаляет ложные строки. Когда я присоединяюсь к любым двум комбинациям таблицы, я получаю дополнительные данные (что я и ожидаю).

Мне трудно присоединиться к третьему столу, мне никогда не приходилось работать со всеми 3.

Пока это мой запрос:

select r1.*, r2.PERSON from table1 r1, table2 r2, table3 r3
where r1.OWNER = r2.OWNER and r2.PERSON = r3.PERSON 

Мой вывод возвращает 8 строк, а некоторые дублируются. Я попытался поиграть с запросом, но он только увеличивает строки.

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

Как мне объединить эти 3 таблицы, чтобы удалить ложные строки, которые я получаю после объединения 2?

Ответы [ 4 ]

0 голосов
/ 30 апреля 2018

Вы, кажется, без потерь разбиваете таблицу на 3 других в рамках получения дизайна 5NF.

Нормализация включает в себя без потерь декомпозицию таблицы на проекции / компоненты, которые естественное соединение возвращают к ней.

(Мы говорим, что оригинал удовлетворяет определенной JD (зависимость соединения), характеризуемой наборами столбцов компонентов. Если в естественном объединении некоторых компонентов появляются ложные (под) строки, то они просто будут в конечном итоге удалены после всех компонентов натурально сочетаются.)

Реляционное естественное соединение имеет синтаксис естественного соединения SQL. (Допустим, нет нулевых или повторяющихся строк, потому что отношения не имеют их.) Это возвращает нам исходную таблицу из ее компонентов:

select *
from table1
natural join table2
natural join table3

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

select table1.type, table2.person, table1.owner
from table1
inner join table2
on table1.owner=table2.owner
-- relevant columns are table1.owner, table1.type, table2.person
inner join table3
on table1.type=table3.type
and table2.person=table3.person
-- relevant columns are table1.owner, table1.type, table2.person

sqlfiddle.

(SQL distinct здесь не требуется. Это следует из того факта, что естественные объединения возвращают строки 1: 1 в определенном соответствии 1: 1 с теми, которые возвращаются реляционным уравнением и его выражением в SQL через внутреннее соединение.)

0 голосов
/ 29 апреля 2018

Многие люди рекомендуют использовать JOIN ... ON для этого. например,

create table t1 as
select 'O1' as owner, 'T1' as type from dual union all
select 'O1', 'T2' from dual union all
select 'O2', 'T1' from dual ;

create table t2 as
select 'O1' as owner, 'P1' as person from dual union all
select 'O1', 'P2' from dual union all
select 'O2', 'P1' from dual ;

create table t3 as
select 'T1' as type, 'P1' as person from dual union all
select 'T2', 'P2' from dual union all
select 'T1', 'P2' from dual ;

Запрос

select
  t1.*
, t2.PERSON 
from   t1  
  join t2  on t1.OWNER = t2.OWNER
  join t3  on t2.PERSON = t3.PERSON and t1.type = t3.type
;

-- result
OWNER  TYPE  PERSON  
O2     T1    P1      
O1     T1    P1      
O1     T2    P2      
O1     T1    P2
0 голосов
/ 29 апреля 2018

Я поместил 1 2 3 в каждое имя столбца, чтобы увидеть, под какой таблицей они были раньше. Первые 3 запроса - это ваши подходы, и 1 из отношений игнорируется в каждом. 4-й подход - все 3 отношения вставлены.

  • , где t1.owner1 = t2.owner2 И t1.type1 = t3.type3 игнорируя t2.person2-t3.person3

    | owner1 | type1 | owner2 | person2 | type3 | person3 |
    |--------|-------|--------|---------|-------|---------|
    |     O1 |    T1 |     O1 |      P1 |    T1 |      P1 |
    |     O1 |    T1 |     O1 |      P1 |    T1 |      P2 |different ppl
    |     O1 |    T1 |     O1 |      P2 |    T1 |      P1 |different ppl
    |     O1 |    T1 |     O1 |      P2 |    T1 |      P2 |
    |     O1 |    T2 |     O1 |      P1 |    T2 |      P2 |different ppl
    |     O1 |    T2 |     O1 |      P2 |    T2 |      P2 |
    |     O2 |    T1 |     O2 |      P1 |    T1 |      P1 |
    |     O2 |    T1 |     O2 |      P1 |    T1 |      P2 |different ppl
    
  • , где t2.owner1 = t1.owner2 И t2.person2 = t3.person3 игнорируя отношение t1.type1-t3.type3

    | owner1 | type1 | owner2 | person2 | type3 | person3 |
    |--------|-------|--------|---------|-------|---------|
    |     O1 |    T1 |     O1 |      P1 |    T1 |      P1 |
    |     O1 |    T2 |     O1 |      P1 |    T1 |      P1 |different types
    |     O2 |    T1 |     O2 |      P1 |    T1 |      P1 |
    |     O1 |    T1 |     O1 |      P2 |    T1 |      P2 |
    |     O1 |    T2 |     O1 |      P2 |    T1 |      P2 |different types
    |     O1 |    T1 |     O1 |      P2 |    T2 |      P2 |different types
    |     O1 |    T2 |     O1 |      P2 |    T2 |      P2 |
    
  • где t3.person2 = t2.person3 И t3.type3 = t1.type1 игнорируя отношение t1.owner1-t2.owner2

    | owner1 | type1 | owner2 | person2 | type3 | person3 |
    |--------|-------|--------|---------|-------|---------|
    |     O1 |    T1 |     O1 |      P1 |    T1 |      P1 |
    |     O2 |    T1 |     O1 |      P1 |    T1 |      P1 |different owners
    |     O1 |    T1 |     O1 |      P2 |    T1 |      P2 |
    |     O1 |    T2 |     O1 |      P2 |    T2 |      P2 |
    |     O2 |    T1 |     O1 |      P2 |    T1 |      P2 |different owners
    |     O1 |    T1 |     O2 |      P1 |    T1 |      P1 |different owners
    |     O2 |    T1 |     O2 |      P1 |    T1 |      P1 |
    
  • , где r1.owner1 = r2.owner2 и r2.person2 = r3.person3 и r1.type1 = r3.type3 (4 результата)

    | owner1 | type1 | owner2 | person2 | type3 | person3 |
    |--------|-------|--------|---------|-------|---------|
    |     O1 |    T1 |     O1 |      P1 |    T1 |      P1 |
    |     O1 |    T1 |     O1 |      P2 |    T1 |      P2 |
    |     O1 |    T2 |     O1 |      P2 |    T2 |      P2 |
    |     O2 |    T1 |     O2 |      P1 |    T1 |      P1 |
    

    Каждый ряд уникален, и каждый тип, человек и владелец одинаковы по строкам.

Нежелательный вывод происходит, когда отношение игнорируется (например, игнорируется отношение person.when person2-person3) person2s через table2.owner2 и person3s через table3.type3 все будут добавлены в результат, как если бы они были нерелевантными полями.

http://sqlfiddle.com/#!9/52075d/23

0 голосов
/ 29 апреля 2018

Проблема заключалась в том, что я связал 2 из 3 таблиц. Мой рабочий запрос ниже:

select r1.*, r2.PERSON from table1 r1, table2 r2, table3 r3 where r1.OWNER = r2.OWNER and r1.TYPE = r3.TYPE and r2.PERSON = r3.PERSON

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

...