在第二个 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'
示例输出:
| LONGSTRING |
|----------------------------------------|
| Mr John Doe MSc A-1100 Vienna (A00025) |
| Mrs Jamie Smith A-4040 Linz (A00026) |
| Jack Jones A-5020 Salzburg (A00027) |
这是我们的数据库设置:
成员:
地址:
头衔:
这是我们需要的输出:
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'
示例输出:
| LONGSTRING |
|----------------------------------------|
| Mr John Doe MSc A-1100 Vienna (A00025) |
| Mrs Jamie Smith A-4040 Linz (A00026) |
| Jack Jones A-5020 Salzburg (A00027) |