2016-09-24 53 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的內部查詢進行分組,但您需要爲其他列使用聚合函數。由於您只解釋了所需輸出的結構,而不是語義,因此我無法利用當前關於您問題的知識來確定您需要的聚合。

一旦找到第一個表的答案,您就可以輕鬆地將其他表添加到選擇中,但是如果數據量較大,可能會遇到一些縮放問題,因此您可能希望一個表格,您可以在這些表格中存儲這些組,在出現變化時對其進行維護並將其用於這些選擇。