SQL объединяет несколько таблиц с отношениями «один ко многим» без «дублирования» - PullRequest
0 голосов
/ 16 мая 2018

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

Примеры таблиц:

Day Table
Day_KEY Day_Label
1       Mon
2       Tues
3       Wed
4       Thur

EstHours Table
EstHours_KEY Day_KEY Est_Hours
1            1       2
2            1       1
3            1       3

ActHours Table
ActHours_KEY Day_KEY Act_Hours
1            1       3
2            1       2
3            1       2

Пример запроса:

select *
from Day
join EstHours on EstHours.Day_KEY = Day.Day_KEY
join ActHours on ActHours.Day_KEY = Day.Day_KEY

Результат:

Day_KEY Day_Label EstHours_KEY Day_KEY Est_Hours ActHours_KEY Day_KEY Act_Hours
1       Mon       1            1       2         1            1       3
1       Mon       1            1       2         2            1       2
1       Mon       1            1       2         3            1       2
1       Mon       2            1       1         1            1       3
1       Mon       2            1       1         2            1       2
1       Mon       2            1       1         3            1       2
1       Mon       3            1       3         1            1       3
1       Mon       3            1       3         2            1       2
1       Mon       3            1       3         3            1       2

Желаемый результат:

Day_KEY Day_Label EstHours_KEY Day_KEY Est_Hours ActHours_KEY Day_KEY Act_Hours
1       Mon       1            1       2         1            1       3
1       Mon       2            1       1         2            1       2
1       Mon       3            1       3         3            1       2

Что я пробовал:

1)
Запрос:

select *
from (
    select *, row_number() over (partition by Day.Day_KEY order by EstHours_KEY) as rn
    from Day
    join EstHours on EstHours.Day_KEY = Day.Day_KEY) rt
join (
    select *, row_number() over (partition by Day_KEY order by ActHours_KEY) as rn
    from ActHours) on ActHours.Day_KEY = Day.Day_KEY and EstHours.rn = ActHours.rn

Результат:

Day_KEY Day_Label EstHours_KEY Day_KEY Est_Hours ActHours_KEY Day_KEY Act_Hours
1       Mon       1            1       2         1            1       3
1       Mon       2            1       1         2            1       2
1       Mon       3            1       3         3            1       2

Это делает то, что мне нужно, если только EstHours не имеет меньше строк, чем ActHours, в этом случае эти строки будут исключены из ActHours.

2)
Запрос:

select *, null, null, null
from Day
join EstHours on EstHours.Day_KEY = Day.Day_KEY

union

select Day.*, null, null, null, ActHours.*
from Day
join ActHours on ActHours.Day_KEY = Day.Day_KEY

Результат:

Day_KEY Day_Label EstHours_KEY Day_KEY Est_Hours ActHours_KEY Day_KEY Act_Hours
1       Mon       1            1       2         null         null    null
1       Mon       2            1       1         null         null    null
1       Mon       3            1       3         null         null    null
1       Mon       null         null    null      1            1       3
1       Mon       null         null    null      2            1       2
1       Mon       null         null    null      3            1       2

Это делает то, что я хочу, за исключением того, что я бы предпочел, чтобы значения были в одних и тех же строках, чтобы максимальное число строк для одного Day_KEY было таким же, как для EstHours или ActHours, в зависимости от того, что больше.

Кто-нибудь знает, как это можно сделать? Я все об этом ошибаюсь?

1 Ответ

0 голосов
/ 16 мая 2018

Похоже, вам нужно предложение group by, которое имеет уникальное / отличающееся поле, принадлежащее таблице «one» в отношении «один ко многим».Например, идентификатор строки.

select * from table_a,table_b,table_c group by table_a.rowid

Это свернет результаты в отдельные строки из table_a, а также позволит результату выбора использовать / включать агрегатные функции, такие как sum (), в полях из table_b или table_c.

В примере, который я использовал, подумайте о каждой строке из table_b и table_c, перекрывающейся с уникальными строками table_a, которые возвращаются.

...