2016-09-24 2 views
-2

У меня есть одна родительская таблица. Продукты с несколькими дочерними таблицами. Шляпы, стелбубы, электрокабели, волоконно-оптические.Объединить строки из таблиц Mulitple в одну таблицу

ProductId -Примерное ключевое поле в таблице продуктов ProductId- ForeignKey поле в шлангах, стелбубах, электрокабелях, волоконно-оптических системах.

стола Продукта имеет от 1 до многих отношений с ребенком таблицами

Я хочу объединить результаты всех таблиц. Например, у продукта P1 есть поле PK ProductId, которое используется во всех дочерних таблицах как FK.

Если таблица шлангов имеет 4 записи с ProductId 50, а таблица Steeltubes имеет 2 записи с ProductId 50, когда я выполняю левое присоединение, тогда левое соединение делает декартовое произведение записей, отображающих 8 записей в качестве результата. Но это должно быть 4 записи.

   ;with HOSESTEELCTE 
     as 
     (
    select '' as ModeType, '' as FiberOpticQty , '' as NumberFibers, '' as FiberLength, '' as CableType , '' as Conductorsize , '' as Voltage,'' as ElecticCableLength , s.TubeMaterial , s.TubeQty, s.TubeID , s.WallThickness , s.DWP ,s.Length as SteelLength , h.HoseSeries, h.HoseLength ,h.ProductId 
    from Hoses h 
    left join 
    (
    --'' as HoseSeries,'' as HoseLength , 
    select TubeMaterial , TubeQty, TubeID , WallThickness , DWP ,  Length,ProductId from SteelTubes 
    ) s on (s.ProductId = h.ProductId) 

) select * from HOSESTEELCTE 
+0

MySQL тег удален, потому что он не имеет КТР. –

ответ

1

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

create table products(pid int); 
insert into products values 
(1),(2); 
create table hoses (pid int,descr varchar(2)); 
insert into hoses values (1,'h1'),(1,'h2'),(1,'h3'),(1,'h4'); 
create table steeltubes (pid int,descr varchar(2)); 
insert into steeltubes values (1,'t1'),(1,'t2'); 
create table electriccables(pid int,descr varchar(2)); 
truncate table electriccables 
insert into electriccables values (1,'e1'),(1,'e2'),(1,'e3'),(2,'e1'); 

это КТР

;with cte as 
    (select row_number() over(partition by p.pid order by datekey) rn, p.pid 
    from dimdate, products p 
    where datekey < 20050105) 

select * from cte 

создать декартовой присоединиться (один из редких ocassions где неявное присоединиться помогает) Pid к гп результате

rn     pid 
-------------------- ----------- 
        1   1 
        2   1 
        3   1 
        4   1 
        1   2 
        2   2 
        3   2 
        4   2 

И если мы добавим дочерние таблицы

;with cte as 
(select row_number() over(partition by p.pid order by datekey) rn, p.pid 
from dimdate, products p 
where datekey < 20050106) 
select c.pid,h.descr hoses,s.descr steeltubes,e.descr electriccables from cte c 
left join (select h.*, row_number() over(order by h.pid) rn from hoses h) h on h.rn = c.rn and h.pid = c.pid 
left join (select s.*, row_number() over(order by s.pid) rn from steeltubes s) s on s.rn = c.rn and s.pid = c.pid 
left join (select e.*, row_number() over(order by e.pid) rn from electriccables e) e on e.rn = c.rn and e.pid = c.pid 
where h.rn is not null or s.rn is not null or e.rn is not null 
order by c.pid,c.rn 

мы получаем это

pid   hoses steeltubes electriccables 
----------- ----- ---------- -------------- 
      1 h1 t1   e1 
      1 h2 t2   e2 
      1 h3 NULL  e3 
      1 h4 NULL  NULL 
      2 NULL NULL  e1 
+0

Спасибо P.Salmon Ты сделал мой день. Вы гениальны. Приветствия !!!!!!!! –

0

В самом деле, результат, имеющий 8 строк можно ожидать, что будет результатом, так как ваши четыре записей соединены с первой записью в другой таблице, а затем ваши четыре записей соединены со второй записью из другой стол, что делает его 4 + 4 = 8.

Тот факт, что вы ожидаете, что 4 результата будут в результатах вместо 8, показывает, что вы хотите использовать какую-то группировку. Вы можете сгруппировать свой внутренний запрос, выпущенный для SteelTubes по ProductId, но тогда вам нужно будет использовать агрегатные функции для других столбцов. Поскольку вы только объяснили структуру желаемого результата, но не семантику, я не могу с моими текущими знаниями о вашей проблеме определить, какие скопления вам нужны.

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

Смежные вопросы