2017-02-24 84 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