SQL外连接一个表有2个表

时间:2017-02-24 21:37:26

标签: mysql sql

我需要一些SQL帮助。我是一个Java交易员,我真的不知道如何提出这个问题。我有3张桌子,称他们为人,儿童,朋友。人是一个ID和一个名字:

|   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从来都不是我最好的主题。现在我将其解析为具有List<>的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

任何能够在我的代码中使用干净循环来构建它的东西。

谢谢!

3 个答案:

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

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

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