MySQL离开了第一个和第二个结果并返回一行

时间:2014-05-26 19:16:42

标签: mysql join left-join

我无法弄清楚如何使用MySQL来解决这个问题。我有一个名为members的表和一个名为contacts的辅助表。在名为contacts的表中,有一个字段用于存储联系人所在成员的id。我需要做的是创建一个查询来获取第一个和第二个联系人并将结果作为一行返回。

示例数据:SQLFiddle

members:
=======
member_id | member_name
----------+------------
1         | John Doe
2         | Bob Smith
3         | Suzy Que

contacts:
=========
contact_id | member_id | contact_name
-----------+-----------+-------------
1          | 1         | Jane Doe
2          | 1         | Johnny Doe
3          | 2         | Betty Smith

注意:会员最多可以有2个联系人,但不需要联系人。

预期结果:

results:
========
member_id | member_name | contact_1   | contact_2
----------+-------------+-------------+------------
1         | John Doe    | Jane Doe    | Johnny Doe
2         | Bob Smith   | Betty Smith | NULL
3         | Suzy Que    | NULL        | NULL

我的第一个查询:

SELECT
  members.member_id,
  members.member_name,
  c1.contact_name AS contact_1,
  c2.contact_name AS contact_2
FROM
  members
  LEFT JOIN contacts AS c1 ON (members.member_id=c1.member_id)
  LEFT JOIN contacts AS c2 ON (members.member_id=c2.member_id)

返回:

results:
========
member_id | member_name | contact_1   | contact_2
----------+-------------+-------------+------------
1         | John Doe    | Jane Doe    | Jane Doe
1         | John Doe    | Jane Doe    | Johnny Doe
1         | John Doe    | Johnny Doe  | Jane Doe
1         | John Doe    | Johnny Doe  | Johnny Doe
2         | Bob Smith   | Betty Smith | Betty Smith
3         | Suzy Que    | NULL        | NULL

如果没有为每个联系人加入做两个不同的子查询,有没有办法做到这一点,因为这看起来效率很低。

修改

根据@Dag Sondre Hansen的建议,这是另一种解决方案,但我希望保留两列。

SELECT
  members.member_id,
  members.member_name,
  group_concat(contacts.contact_name separator ';') as contacts
FROM
  members
  LEFT JOIN contacts ON (members.member_id=contacts.member_id)
GROUP BY
  members.member_id;

2 个答案:

答案 0 :(得分:3)

SELECT
  members.member_id,
  members.member_name,
  c1.contact_name AS contact_1,
  c2.contact_name as contact_2
FROM
  members
  LEFT JOIN contacts AS c1 ON (members.member_id=c1.member_id)
  LEFT JOIN contacts as c2 on (members.member_id=c2.member_id AND c1.contact_id <> c2.contact_id)
GROUP BY members.member_id

这对我有用。

注意:这实际上只有每个成员最多2个联系人的数据约束才有效。如果此约束发生更改,或者程序未强制执行,则此处的SQL将产生不同的结果。

答案 1 :(得分:1)

如果是一种解决方法而不是实际的解决方案,可能会更多,但这里有:

SELECT   
    members.member_id,   members.member_name,  
    GROUP_CONCAT(c1.contact_name) AS contacts 
FROM   
    members   
    LEFT JOIN contacts AS c1 ON (members.member_id=c1.member_id) 
GROUP BY    
    members.member_id;

会员名称将在同一列中弹出。