在第二个 table 中正确显示 mySQL 具有多个匹配项的 LEFT JOIN

Displaying mySQL LEFT JOIN with multiple matches in second table correctly

这是我们的数据库设置:

成员:

地址:

头衔:

这是我们需要的输出:

Mr John Doe Msc A-1100 Vienna (A00025)
Mrs Jamie Smith A-4040 Linz (A00026)
Jack Jones A-5020 Salzburg (A00027)

到目前为止,这是我们的 mySQL 声明:

SELECT T1.member_id, T1.surname, T1.firstname, T2.country, T2.zip, T2.town,
    T3.titel, T3.position FROM members T1 
    LEFT JOIN addresses T2
    ON T1.member_id = T2.member_id 
    LEFT JOIN titles T3
    ON T1.member_id = T3.member_id
    WHERE T2.type = "invoice"

这给了我们:

Mr John Doe A-1100 Vienna (A00025)
John Doe MSc A-1100 Vienna (A00025)
Mrs Jamie Smith A-4040 Linz (A00026)
Jack Jones A-5020 Salzburg (A00027)

我们如何防止 John Doe 被两次列出? 我们如何在同一行中获得两个标题?

感谢您的帮助!!

假设您最多只有 1 个之前的标题和 1 个之后的标题:

SELECT T1.member_id, T1.surname, T1.firstname, 
    T2.country, T2.zip, T2.town,
    T3.titel AS titelBefore,
    T4.titel AS titelAfter,
FROM members T1 
   INNER JOIN addresses T2 ON (T1.member_id = T2.member_id) 
   LEFT JOIN titles T3 ON (T1.member_id = T3.member_id AND T3.position = "before")
   LEFT JOIN titles T4 ON (T1.member_id = T4.member_id AND T4.position = "after")
 WHERE T2.type = "invoice"

请注意地址的 INNER JOIN,您不需要 LEFT JOIN,因为您在 WHERE

中声明了 T2.type = "invoice"

此处的关键是尽可能多地加入标题 table,因为可以有不同的标题位置,这样您就可以从不同的来源访问每个不同的 title/position。

如果您想从查询中生成类似 Mr Doe John MSc A-1100 Vienna (A00025) 的字符串,您可以使用 concat 函数来构建它。

SELECT 
  concat(
    case when t1.titel is null then '' else t1.titel end, 
    case when t1.titel is null then '' else ' ' end,
    m.firstname,  ' ',
    m.surname,  ' ',
    case when t2.titel is null then '' else t2.titel end,
    case when t2.titel is null then '' else ' ' end,
    a.country, '-', a.zip,  ' ',
    a.town, 
    ' (', m.member_id , ')'   
  ) AS LongString       

FROM members m 
JOIN addresses a
    ON m.member_id = a.member_id AND a.type = 'invoice'
LEFT JOIN titles t1
    ON m.member_id = t1.member_id AND t1.position = 'Before' 
LEFT JOIN titles t2
    ON m.member_id = t2.member_id AND t2.position = 'After'

Sample SQL Fiddle

示例输出:

|                             LONGSTRING |
|----------------------------------------|
| Mr John Doe MSc A-1100 Vienna (A00025) |
|   Mrs Jamie Smith A-4040 Linz (A00026) |
|    Jack Jones A-5020 Salzburg (A00027) |