2011-09-14 108 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對不起,下次你在丹麥時,我會給你買一瓶啤酒。 –

相關問題