2017-02-24 89 views
1

我需要一些SQL幫助。我是交易的Java人,我甚至不知道如何提出這個問題。我有3張桌子,叫他們人,孩子,朋友。人是一個ID和一個名稱:SQL外連接一個表與兩個表

| id | name | 
--------------------- 
| 1 | Joe  | 

讓我們說孩子是一樣的,但用FK回人

| id | personId | name | 
------------------------------------- 
| 1 |  1  | Frank | 
| 2 |  1  | Dan | 

和朋友是一回事

| id | personId | name | 
------------------------------------- 
| 1 |  1  | Will | 
| 2 |  1  | Bob | 

顯然,這是我真正的問題的簡化版本,但結構是相同的。我需要把所有這些數據在一個SQL拉這樣的,我把它恢復

| personId | personName | childId | childName | friendId | friendName 
------------------------------------------------------------------------------------------ 
|  1  | Joe  |  1  | Frank | null  | null 
|  1  | Joe  |  1  | Dan  | null  | null 
|  1  | Joe  | null | null |  1  | Will 
|  1  | Joe  | null | null |  2  | Bob 

我曾嘗試多個連接技術,但似乎無法破解它。 SQL從來不是我最好的主題。現在,我正與朋友和兒童名單<>所以顯然這將工作太解析此爲Java對象者:

| personId | personName | childId | childName | friendId | friendName 
------------------------------------------------------------------------------------------ 
|  1  | Joe  | null | null | null  | null 
| null | null  |  1  | Frank | null  | null 
| null | null  |  1  | Dan  | null  | null 
| null | null  | null | null |  1  | Will 
| null | null  | null | null |  2  | Bob 

凡是允許乾淨的for循環在我的代碼來構建這個。

謝謝!

+0

我不是專家,但有兩個全外連接上person.id = children.personId和person.id = friends.personId應該工作。你試過了什麼,結果是什麼? – mreff555

+0

@ mreff555 this is tagged MySQL – Strawberry

回答

4
select 
    p.id as personId 
    , p.name as personName 
    , c.id as childId 
    , c.name as childName 
    , null as friendId 
    , null as friendName 
from person p 
    inner join child c 
    on p.id = c.personId 
union all 
select 
    p.id as personId 
    , p.name as personName 
    , null as childId 
    , null as childName 
    , f.id as friendId 
    , f.name as friendName 
from person p 
    inner join friend f 
    on p.id = f.personId; 

rextester :http://rextester.com/BSPEC33394

回報:

+----------+------------+---------+-----------+----------+------------+ 
| personId | personName | childId | childName | friendId | friendName | 
+----------+------------+---------+-----------+----------+------------+ 
|  1 | joe  | 1  | frank  | NULL  | NULL  | 
|  1 | joe  | 2  | dan  | NULL  | NULL  | 
|  1 | joe  | NULL | NULL  | 1  | will  | 
|  1 | joe  | NULL | NULL  | 2  | bob  | 
+----------+------------+---------+-----------+----------+------------+ 
+0

你確定內部連接會返回空值嗎?我認爲你應該使用左外連接 – bksi

+0

@bksi點擊rextester鏈接,看看看看。 http://rextester.com/BSPEC33394 – SqlZim

1

你可以外聯同孩子和朋友的工會,然後檢查其中兩個你與匹配,以確定哪些輸出中的每一列(使用case when):

select person.id, 
      person.name, 
      case when rel.kind = 1 then rel.id end as childId, 
      case when rel.kind = 1 then rel.name end as childName, 
      case when rel.kind = 2 then rel.id end as friendId, 
      case when rel.kind = 2 then rel.name end as friendName 
from  person 
left join (
      select id, personId, name, 1 as kind 
      from children 
      union all 
      select id, personId, name, 2 as kind 
      from friends 
     ) as rel 
     on rel.personId = person.id 
order by person.id, 
      rel.kind 
      rel.id 
0

您可以使用LEFT JOIN以達致這:

SELECT 
    p.id as personId 
    , p.name as personName 
    , c.id as childId 
    , c.name as childName 
    , f.id as friendId 
    , f.name as friendName 
FROM person p 
LEFT OUTER JOIN child c ON p.id = c.personId 
LEFT OUTER JOIN friend f ON p.id = f.personId; 

更多信息連接,你可以在這裏閱讀: https://www.w3schools.com/sql/sql_join_left.asp