2016-05-20 40 views
0

需要一些幫助來構建我的查詢。我想我需要一個子查詢,但我不太清楚如何在我的上下文中使用它們。我有以下表和數據,從我的查詢輸出不太正確,可能子查詢呢?

people 
ID, Name 
1, David 
2, Victoria 
3, Brooklyn 
4, Tom 
5, Katie 
6, Suri 
7, Kim 
8, North 
9, Kanye 
10,James 
11,Grace 


relationship 
peopleID, Relationship, relatedID 
3,Father,1 
3,Mother,2 
6,Father,4 
6,Mother, 5 
8,Mother,7 
8,Mother,9 
11,Father,10 

我有以下查詢

SELECT DISTINCT p.ID, p.name, f.ID, f.name, m.ID, m.name 
FROM people AS p 
LEFT JOIN relationship AS fr ON p.ID = fr.peopleID 
LEFT JOIN people AS f ON fr.relatedID = f.ID 

LEFT JOIN relationship AS mr ON p.ID = mr.peopleID 
LEFT JOIN people AS m ON mr.relatedID = m.ID 
WHERE p.ID IN(3,6,8,11) 
AND (
    mr.Relationship IN('Mother','Stepmother') 
OR fr.Relationship IN('Father','Stepfather') 
    ) 

上面的查詢輸出以下數據

3,Brooklyn,1,David,1,David 
3,Brooklyn,1,David,2,Victoria 
3,Brooklyn,2,Victoria,2,Victoria 
6,Suri,4,Tom,4,Tom 
6,Suri,4,Tom,5,Katie 
6,Suri,5,Katie,5,Katie 
8,North,7,Kim,7,Kim 
8,North,9,Kanye,7,Kim 
8,North,9,Kanye,9,Kanye 
11,Grace,10,James,10,James 

我有點明白是怎麼回事,因此我想我可能需要一個子查詢或者可能是一個工會來讓父母先獲得這些結果。我正試圖輸出以下內容,有誰能幫忙嗎?

3,Brooklyn,1,David,2,Victoria 
6,Suri,4,Tom,5,Katie 
8,North,9,Kanye,7,Kim 
11,Grace,10,James,, <-should display no mother details (same for the father if father was not in the data) 
+0

你使用SQL Server? –

回答

0

對不起,我無法檢查查詢現在。這是否工作?

SELECT DISTINCT p.ID, p.name, f.ID, f.name, m.ID, m.name 
FROM people AS p 
LEFT JOIN relationship AS fr 
     ON p.ID = fr.peopleID 
     AND fr.relationship IN ('Father','Stepfather') 
LEFT JOIN people AS f 
     ON fr.relatedID = f.ID 
LEFT JOIN relationship AS mr 
     ON p.ID = mr.peopleID 
     AND mr.relationship IN('Mother','Stepmother') 
LEFT JOIN people AS m 
     ON mr.relatedID = m.ID 
WHERE p.ID IN(3,6,8,11) 

重點是擺脫使用(哪裏A或B)連同左加入。它給結果的邏輯帶來太多的不確定性

+0

這似乎從最初的測試工作,沒有意識到你可以在連接本身使用IN過濾器。總是認爲IN必須在WHERE子句中進行。 – JK36

+0

如果有問題,IN('B','C')與(A ='B'或A ='C')沒有區別。左連接總是會給你帶來一些東西 - 它會是NULL還是實際值取決於連接過濾器。順便說一句,如果你想過濾沒有父母在場的人,你將不得不使用(..)WHERE(f.name IS NOT NULL或m.name IS NOT NULL) - 在這種情況下where子句不可能替換 – NLink

+0

select cast (p.id as nvarchar(max))+','+ p.name +(SELECT cast(p1.id as varchar(max))+','+ p1.name FROM relationship r1內部加入r1上的人員p1。 relatedID = p1.ID其中r1.peopleID = p.id用於xml路徑(''))來自關係r內部連接人p上p.ID = r.peopleID組p.ID,p.name – Sanjay

0

這是你想要的嗎?

SELECT p.ID, p.Name, p1.ID, p1.Name 
FROM relationship r 
    INNER JOIN people p ON p.ID = r.peopleID 
    INNER JOIN people p1 ON p1.ID = r.relatedID 

選擇流延(如p.id爲nvarchar(最大))+ '' + p.name +(SELECT鑄造(p1.id爲varchar(最大))+ '' + p1.name FROM關係r1 inner join p1 on r1.relatedID = p1.ID其中r1.peopleID = p.id for xml path(''))from relation r內連接人p上p.ID = r.peopleID group by p.ID ,p.name

讓我知道你是否想要更多。

+0

select cast(p .ID如爲nvarchar(最大))+ '' + p.name +( \t SELECT鑄造(p1.id爲varchar(最大))+ '' + p1.name \t FROM關係R1 \t \t內連接關於r1.relatedID = p1.ID \t其中r1.peopleID = p.id \t用於XML路徑( '') ) 從關係式R \t內由p.ID,p.name上p.ID = r.peopleID 組加入人p – Sanjay

0

即使你已經接受了答案,但我還是要提供我的:

WITH familly AS 
(
    SELECT 
     child.ID AS childID 
     ,child.Name AS childName 
     ,Relationship AS relationship 
     ,parent.ID AS parentID 
     ,parent.Name AS parentName 
    FROM relationship 
    LEFT JOIN people AS child ON child.ID = peopleID 
    LEFT JOIN people AS parent ON parent.ID = relatedID 
) 
SELECT 
    t.childID 
    ,t.childName 
    ,STUFF(ISNULL((
     SELECT ', ' + CAST(x.parentID AS NVARCHAR(10)) + ', ' + x.parentName 
     FROM familly x 
     WHERE x.childID = t.childID 
     GROUP BY x.parentID, x.parentName 
     FOR XML PATH (''), TYPE 
    ).value('.','VARCHAR(max)'), ''), 1, 2, '') [Parents] 
FROM familly t 
WHERE t.childID IN(3,6,8,11) 
GROUP BY t.childID, t.childName 

有就不太LEFT JOIN,更具可讀性。你應該使用表relationship啓動法定的繼承權 ,所以:一邊

  • ,你可以對對方加入people兒童
  • ,可以聯合people作爲父母。

然後,我用陳述WITH來提供更好的可讀性。最後, 操作STUFF (Transact-SQL)將多個字符串(父母)連接成一行。

參考文獻: