SQL - 1父表,2子表 - 为子表中的每一行返回单行

时间:2011-09-14 11:40:00

标签: sql join union

表A

  • PARENTID
  • 名称

表B

  • BKEY
  • PARENTID
  • DescB

表C

  • CKEY
  • PARENTID
  • DescC

我需要为B / A中与父ID匹配的每个组合数据行返回1行,如果其中一个子表的行数多于另一个子行,则应该返回一行,其中包含该描述的空值。 / p>

例如,如果数据如下

表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

在没有工会的情况下,有没有这样做呢?

3 个答案:

答案 0 :(得分:2)

我真的希望这是MYSQL问题

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/

答案 1 :(得分: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

答案 2 :(得分:0)

您可以分两步实施:

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

2)加入关于第1步记录数量的第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