2011-09-14 75 views
2

表ASQL - 1个父表,2个表 - 每个行中的子表中返回一行

  • PARENTID
  • 名称

表B

  • BKey
  • PARENTID
  • DescB

表C

  • CKEY
  • PARENTID
  • DescC

我需要返回1行进行数据的每个组合排在B/A tha t匹配父ID,并且如果其中一个子表的行数多于另一个,则应为该描述使用空值返回一行。

例如,如果该数据是如下

表A

1 FirstParent 
2 Second Parent 

表B

1 1 BDesc1 
2 1 BDesc2 
3 2 P2BDesc1 

表C

1 1 CDesc1 
2 2 P2CDesc1 
3 2 P2CDesc2 

如果我找回基于FirstParent,结果应该是:

1 FirstParent BDesc1 CDesc1 
1 FirstParent BDesc2 NULL 

如果我找回基于SecondParent,结果应该是:

2 SecondParent P2BDesc1 P2CDesc1 
2 SecondParent NULL  P2CDesc2 

反正有这样做没有的有工会吗?

回答

2
declare @ParentID int 
set @ParentID = 1 

select a.name, 
     bc.descb, 
     bc.descc 
from TableA as a 
    cross join (select b.descb, 
        c.descc 
       from (select *, 
          row_number() over(order by b.bkey) as rn 
         from TableB as b 
         where b.parentid = @parentid) as b 
       full outer join 
        (select *, 
          row_number() over(order by c.ckey) as rn 
         from TableC as c 
         where c.parentid = @parentid) as c 
        on b.rn = c.rn) as bc 
where a.parentid = @parentid 

试试这里:http://data.stackexchange.com/stackoverflow/qt/112538/

编辑:使用ExternalKey查询多个PARENTID的

建议指标的版本:

create index IX_B_ParentID on TableB(ParentID) include (DescB) 
create index IX_C_ParentID on TableC(ParentID) include (DescC) 

我会创建包含相匹配的ExternalKey的PARENTID的,然后用这个来代替表变量查询中的TableA。

declare @ExternalKey int = 1 

declare @T table(ParentID int primary key, Name varchar(20)) 
insert into @T (ParentID, Name) 
select ParentID, NAme 
from TableA 
where ExternalKey = @ExternalKey 


select a.name, 
     bc.descb, 
     bc.descc 
from @T as a 
    inner join (select b.descb, 
        c.descc, 
        coalesce(b.ParentID, c.ParentID) as ParentID 
       from (select b.ParentID, 
          b.DescB, 
          row_number() over(partition by b.ParentID order by b.bkey) as rn 
         from TableB as b 
         where b.parentid in (select ParentID from @T)) as b 
       full outer join 
        (select c.ParentID, 
          c.DescC, 
          row_number() over(partition by c.ParentID order by c.ckey) as rn 
         from TableC as c 
         where c.parentid in (select ParentID from @T)) as c 
        on b.rn = c.rn and 
        b.ParentID = c.ParentID) as bc 
    on a.ParentID = bc.ParentID 
+1

我们有不同的方式来理解问题,您的解决方案是完全有效的。 +1。我认为整个结果应该结合起来而不使用工会。但它也可能是OP希望每个A.parentID在没有联合的情况下被检索的子结果。 –

+0

这回答了我问的问题。所以,我会标记它的答案。不过,我确实简化了一下。另外在父表上a是一个ExternalKey列,我通常会通过外部键来获取,因此它必须根据externalkey检索具有多个parentid的结果集,并且在更改示例时引用表a中的parentid时遇到问题。 – leifre

+0

@leifre - 修改@ t-clausen.dk提供的答案会更容易,以适应您的要求。只需在主查询中添加一个where子句即可。 '哪里a.ExternalKey = SomeValue'。 –

0

可以在2个步骤实现:

1)每一个孩子表中计算的记录数。

2)加入从第一步

select a.ParentId, a.Name, b.DescB, c.DescC 
from (
    select ParentId, (select count(*) from b where a.ParentId = b.ParentId) as cntB, 
    (select count(*) from c where a.ParentId = b.ParentId) as cntC 
from a 
left join b cntB >= cntC and a.ParentId = b.ParentId 
left join c cntB < cntC and a.ParentId = c.ParentId 
+0

我试图做这个工作,但放弃了几个不正确的语法。 –

+0

虽然有趣的想法,wouldnt想到采取这种方法 – leifre

2

就到的记录数,我是真的希望这是MSSQL问题

declare @a table(
ParentID int, 
Name varchar(15)) 

declare @b table(
BKey int, 
ParentID int, 
DescB varchar(10)) 


declare @c table(
CKey int, 
ParentID int, 
DescC varchar(10)) 

insert @a values (1,'FirstParent') 
insert @a values (2,'SecondParent') 

insert @b values(1, 1, 'BDesc1') 
insert @b values(2, 1, 'BDesc2') 
insert @b values(3, 2, 'P2BDesc1') 

insert @c values(1, 1, 'CDesc1') 
insert @c values(2, 2, 'P2CDesc1') 
insert @c values(3, 2, 'P2CDesc2') 

;with b as 
(
    select DescB, ParentID, row_number() over (partition by parentid order by DescB) rn from @b 
), 
c as 
(
    select DescC, ParentID, row_number() over (partition by parentid order by DescC) rn from @c 
), 
d as (
    select DescB, DescC, coalesce(b.parentid, c.parentid) parentid from b 
    full outer join c 
    on c.parentid = b.parentid and c.rn = b.rn 
) 
select a.ParentID, a.Name, d.DescB, d.DescC from @a a 
join d 
on a.parentid = d.parentid 
order by 1 

尝试在这里第一或第二个表: http://data.stackexchange.com/stackoverflow/q/112537/

+0

Otroligt :)这只是很多。平等直到“试试这里”链接。 +1。 49秒后。 –

+1

@MikaelEriksson对不起,下次你在丹麦时,我会给你买一瓶啤酒。 –

相关问题