2016-09-24 84 views
-2

我有一个父表有多个子表的产品 - 软管,钢管,ElectricCables,FiberOptics。将多行表中的行组合成单表

ProductId - 产品表中的主要关键字段 ProductId-软管,钢管,ElectricCables,FiberOptics中的ForeignKey字段。

产品表中有1与子表

我想所有表的结果,并结合大量的关系。 对于eg - 产品P1具有PK字段ProductId,它在所有子表中用作FK。

如果软管表有4个记录与ProductId 50和Steeltubes表有4个记录与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'); 

这个CTE

;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 结果

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 

我们得到删除,因为它不具备这个CTE

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结果显示你想使用某种分组。您可以按照ProductId对发布给SteelTubes的内部查询进行分组,但您需要为其他列使用聚合函数。由于您只解释了所需输出的结构,而不是语义,因此我无法利用当前关于您问题的知识来确定您需要的聚合。

一旦找到第一个表的答案,您就可以轻松地将其他表添加到选择中,但是如果数据量较大,可能会遇到一些缩放问题,因此您可能希望一个表格,您可以在这些表格中存储这些组,在出现变化时对其进行维护并将其用于这些选择。