内部或左侧将多个表记录连接到单个行中

时间:2010-04-02 15:26:22

标签: mysql left-join inner-join

电话表

+----------------+-------------+
| Field          | Type        |
+----------------+-------------+
| f_id           | int(15)     |
| f_client_id    | int(11)     |
| f_phone_type   | varchar(50) |
| f_phone_number | varchar(13) |
+----------------+-------------+

客户表

+-----------------------------+--------------+------+-----+
| Field                       | Type         | Null | Key |
+-----------------------------+--------------+------+-----+
| f_id                        | int(15)      | NO   | PRI |
| f_first_name                | varchar(13)  | YES  | MUL |
| f_mi                        | char(1)      | YES  |     |
| f_last_name                 | varchar(20)  | NO   | MUL |
+-----------------------------+--------------+------+-----+

假设:

  1. “电话表”中的每条记录都属于“客户表”中的一条记录。
  2. “客户表”中的每条记录在“电话表”中都可以包含0条或更多条记录。
  3. 简单翻译:客户可以拥有0个或更多电话号码
  4. 通过标准的LEFT或INNER加入,我得到这样的结论:

    +------------+------------+--------------+
    | name       | Phone Type | Phone Number |
    +------------+------------+--------------+
    | John Smith | Home       | 712-555-6987 |
    | John Smith | Work       | 712-555-1236 |
    +------------+------------+--------------+
    

    我需要一个查询,它会为我提供属于给定客户的工作和家庭电话号码

    +------------+----------------+--------------+
    | Name       | Work Number    | Home Number  |  
    +------------+----------------+--------------+
    | John Smith | 712-555-1236   | 712-555-6987 |
    +------------+----------------+--------------+
    

    是否可以进行LEFT或INNER连接,然后将这些结果合并为一行?我已经看到了类似的问题,但给出的例子比我追求的要复杂得多:

    类似问题

    由于

3 个答案:

答案 0 :(得分:1)

虽然您可以将多个数字(任意)加入一个字段:

SELECT
  CONCAT(f_first_name, ' ', f_last_name) as Client_Name,
  GROUP_CONCAT(IF(phone_type='work',f_phone_number, NULL)) as Work_Numbers,
  GROUP_CONCAT(IF(phone_type='home',f_phone_number, NULL)) as Home_Numbers
FROM clients
JOIN phone
  USING (f_id)
WHERE phone_type IN ('home', 'work')
GROUP BY f_id;

答案 1 :(得分:0)

SELECT CONCAT(c.f_first_name, ' ', c.f_last_name) as Client_Name, 
       wp.f_phone_number as Work_Number,
       hp.f_phone_number as Home_Number

  FROM clients c
       LEFT OUTER JOIN phone hp
       ON hp.f_client_id = c.f_id
    AND
       hp.phone_type = 'home'
       LEFT OUTER JOIN phone wp
       ON wp.f_client_id = c.f_id
    AND
       wp.phone_type = 'work'

使用LEFT OUTER JOIN,您仍会获得缺少数字的客户的行。如果您不想看到这些,请更改为INNER JOIN。

编辑:正如尼克善意地提醒我的那样,这将为具有多个电话号码的客户返回多行。获得所需数据后,您将面临演示问题。您可以在应用程序层中处理它,或者牺牲SQL神并查看MySQL的GROUP_CONCAT()函数。

答案 2 :(得分:0)

特定客户记录可以拥有多少个工作或家庭电话号码?如果它可以很多,那么不,没有办法做出一行。如果每个最多可以有1个,那么您可以两次加入电话号码表。