一对多加入

One-to-Many Join

我的数据库中有三个 table - APPLICATIONAPPLICANTADDRESS

APPLICATION 中有 1 行。

APPLICANT 可以通过 APPLICATION_ID.

将 1 或 2 行链接回 APPLICATION

ADDRESS 可以通过 APPLICANT_ID.

将 1、2 或 3 行链接回 APPLICANT

APPLICATION -> (1-to-many on APPLICATION_ID) -> APPLICANT -> (1-to-many on APPLICANT_ID) -> ADDRESS

我需要编写一个查询,从每个 table(从 'all information' 更改)中提取特定字段到 1 个结果集中。结果需要在一个结果行中包含每个应用程序的所有可能信息。有人可以为我指明最佳解决方案的方向吗?

我希望问题很清楚。我已经通过 SO 进行了搜索,但实际上只能找到一些特定案例的答案,而没有找到关于一对多连接的一般信息。

好的,我想我应该详细说明一下,以帮助真正花时间思考这个问题的人。这是来自所有三个 table 的一些示例虚拟数据。

APPLICATION
-----------
APPLICATION_ID|APP1|APP2|OTHER_STUFF
1             |1   |1   |x

APPLICANT
---------
APPLICANT_ID|APPLICATION_ID|FORENAME|OTHER_STUFF
1           |1             |Homer   |x
2           |1             |Marge   |x

ADDRESS
-------
ADDRESS_ID|APPLICANT_ID|STREET           |OTHER_STUFF
1         |1           |Sesame Street    |x
2         |1           |Evergreen Terrace|x
3         |2           |Evergreen Terrace|x

SQL 查询的结果看起来像这样(希望如此);

APPLICATION_ID|APPLICANT_ID1|FORENAME1|ADDRESS_ID1|STREET1      |ADDRESS_ID2|STREET2          |APPLICANT_ID2|FORENAME_2|ADDRESS_ID3|STREET3
1             |1            |Homer    |1          |Sesame Street|2          |Evergreen Terrace|2            |Marge     |3          |Evergreen Terrace

谢谢

select APPLICATION.*, APPLICANT.*, ADDRESS.* 
  from APPLICATION
  join APPLICANT 
    on APPLICATION.APPLICATION_ID = APPLICANT.APPLICATION_ID
  join ADDRESS
    on APPLICANT.APPLICATION_ID = APPLICANT.APPLICATION_ID

您一定会在以下查询中使用它。希望对你有帮助。

SELECT * FROM APPLICATION as App

INNER JOIN APPLICANT as A1 on A1.APPLICATION_ID = App.APPLICATION_ID

INNER JOIN ADDRESS as A2 on A2.APPLICANT_ID = A1.APPLICANT_ID
; WITH applicants AS (
  SELECT applicant_id
       , application_id
       , forename
       , other_stuff
       , Row_Number() OVER (PARTITION BY application_id ORDER BY applicant_id) As sequence
  FROM   applicant
)
, addresses AS (
  SELECT address_id
       , applicant_id
       , street
       , other_stuff
       , Row_Number() OVER (PARTITION BY applicant_id ORDER BY address_id) As sequence
  FROM   address
)
SELECT application.application_id
     , first_applicants.applicant_id As applicant_id1
     , first_applicants.forename As forename1
     , first_applicants_first_addresses.address_id As address_id1
     , first_applicants_first_addresses.street As street1
     , first_applicants_second_addresses.address_id As address_id2
     , first_applicants_second_addresses.street As street2
     , second_applicants.applicant_id As applicant_id2
     , second_applicants.forename As forename2
     , second_applicants_first_addresses.address_id As address_id3
     , second_applicants_first_addresses.street As street3
     , second_applicants_second_addresses.address_id As address_id4
     , second_applicants_second_addresses.street As street4     
FROM   application
 LEFT
  JOIN applicants As first_applicants
    ON first_applicants.application_id = application.application_id
   AND first_applicants.sequence = 1
 LEFT
  JOIN addresses As first_applicants_first_addresses
    ON first_applicants_first_addresses.applicant_id = first_applicants.applicant_id
   AND first_applicants_first_addresses.sequence = 1
 LEFT
  JOIN addresses As first_applicants_second_addresses
    ON first_applicants_second_addresses.applicant_id = first_applicants.applicant_id
   AND first_applicants_second_addresses.sequence = 2
 LEFT
  JOIN applicants As second_applicants
    ON second_applicants.application_id = application.application_id
   AND second_applicants.sequence = 2
 LEFT
  JOIN addresses As second_applicants_first_addresses
    ON second_applicants_first_addresses.applicant_id = second_applicants.applicant_id
   AND second_applicants_first_addresses.sequence = 1
 LEFT
  JOIN addresses As second_applicants_second_addresses
    ON second_applicants_second_addresses.applicant_id = second_applicants.applicant_id
   AND second_applicants_second_addresses.sequence = 2
WHERE  application.application_id = 1
;