Sql server 2012 将多个表中的行合并到单个表中
我有一个父表产品和多个子表-软管,钢管,电缆,光纤光学 ProductId—产品表中的主键字段 ProductId-软管、钢管、电缆、光纤光学领域的国外关键领域 产品表与子表具有1对多关系 我想合并所有表的结果。 对于eg-产品P1具有PK字段ProductId,该字段在所有子表中用作FK 当我执行左连接时,如果软管表有4条ProductId为50的记录,而钢管表有2条ProductId为50的记录,则左连接执行记录的笛卡尔乘积,结果显示8条记录,但它应该是4条记录Sql server 2012 将多个表中的行合并到单个表中,sql-server-2012,database-administration,Sql Server 2012,Database Administration,我有一个父表产品和多个子表-软管,钢管,电缆,光纤光学 ProductId—产品表中的主键字段 ProductId-软管、钢管、电缆、光纤光学领域的国外关键领域 产品表与子表具有1对多关系 我想合并所有表的结果。 对于eg-产品P1具有PK字段ProductId,该字段在所有子表中用作FK 当我执行左连接时,如果软管表有4条ProductId为50的记录,而钢管表有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
事实上,具有8行的结果可以预期为结果,因为您的四条记录与另一个表中的第一条记录联接,然后您的四条记录与另一个表的第二条记录联接,使其为4+4=8 您希望结果中有4条记录而不是8条记录,这一事实表明您希望使用某种分组。您可以按ProductId对为钢管发出的内部查询进行分组,但随后需要对其他列使用聚合函数。由于您只解释了所需输出的结构,而没有解释语义,因此我无法用我目前对您的问题的了解来确定您需要什么聚合
找到第一个表的答案后,您也可以轻松地将其他表添加到选择中,但如果数据较大,则可能会遇到一些缩放问题,因此您可能希望有一个存储这些组的表,当某些内容发生更改时维护它,并将其用于这些选择。假设子表之间没有关系,并且您只需要一个组成产品的所有子实体的列表,您可以生成一个cte,该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
如果我们添加子表
;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
MySQL标记已删除,因为它没有CTE。
;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