【问题标题】:MySQL inner join AND turn rows into columsMySQL 内连接 AND 将行转换为列
【发布时间】:2013-10-23 17:57:38
【问题描述】:

我很难弄清楚如何为我的查询创建正确的语法。

这就是我想要的。我有 2 张桌子。

Table 1 : Fields  (user_id, name)
Table 2 : Fields  (user_id, type, are_code, phone_number).

表 1 每个 user_id 只能有 1 条记录。

1 | John Doe

表 2 每个 user_id 最多可以有 3 条记录:

1 | Home | 123 | 456.4567
1 | Work | 000 | 987.1467
1 | Mobi | 098 | 987.1756

我怎样才能选择所有内容,以便我的表将导致 1 条记录被拉到这样:

user_id | name | home# | work# | mobi#

我试过这个,它根据表 2 中的条目数量复制和加倍行。

SELECT a.user_id, 
       b.area_code, b.phone_number
FROM users a
INNER JOIN user_contact_phones b ON a.user_id = b.user_id

不幸的是返回了 3 行,这不好:(。

1 | John Doe | area | home# | 
1 | John Doe | area | work# |
1 | John Doe | area | mobi# |

任何帮助和/或指点将不胜感激。

【问题讨论】:

  • 您可以为同一个用户拥有多个 HOME 类型吗?

标签: php mysql inner-join


【解决方案1】:

试试这个:

SELECT
  u.user_id,
  u.name,
  MAX(CASE WHEN p.type = 'Home' THEN phone_number END) HomeNumber,
  MAX(CASE WHEN p.type = 'Work' THEN phone_number END) WorkNumber,
  MAX(CASE WHEN p.type = 'Mobi' THEN phone_number END) MobiNumber
FROM phones p
JOIN users u ON p.user_id = u.user_id
GROUP BY u.user_id, u.name

输出:

| USER_ID |     NAME | HOMENUMBER | WORKNUMBER | MOBINUMBER |
|---------|----------|------------|------------|------------|
|       1 | John Doe |   456.4567 |   987.1467 |   987.1756 |

小提琴here.

还请注意,如果u.user_id 确定u.name... 很可能是这种情况,您可以删除u.name,因为它似乎是主键。这会加快速度。

注意:这假设您不能为同一个用户拥有多个相同的类型(就像在您的示例数据中一样,它只有一列用于家庭、工作和移动。

【讨论】:

  • 仅供参考,将u.name 排除在GROUP BY 子句之外是一个MySQL 扩展。标准 SQL 要求所有非聚合列都在 GROUP BY 中。
  • @Barmar。当然。该问题被标记为 MySQL,因此不使用此类功能将没有任何意义并导致性能下降。
  • 我认输,这是一个比我之前提供的更优雅的答案。
  • @DavidF 我会说它更有效,因为它可以节省一些连接。在 MySQL 中进行旋转时,没有elegant 答案:P
【解决方案2】:

使用user_contact_phones.type 获得您想要的确切信息,例如-

SELECT a.user_id, 
       b.area_code, b.phone_number
FROM users a
INNER JOIN user_contact_phones b ON a.user_id = b.user_id where b.type='Home'

【讨论】:

  • 这只会提取“家庭”电话号码,我需要所有 3 个号码并将它们放在 3 个单独的列中。
【解决方案3】:

这是一个可行的解决方案:

select u.user_id, u.name,
    thome.area_code as home_area_code, thome.phone_number as home_phone_number,
    twork.area_code as work_area_code, twork.phone_number as work_phone_number,
    tmobi.area_code as mobi_area_code, tmobi.phone_number as mobi_phone_number  
from table1 u
    left outer join table2 thome on u.user_id = thome.user_id and thome.type = 'Home'
    left outer join table2 twork on u.user_id = twork.user_id and twork.type = 'Work'
    left outer join table2 tmobi on u.user_id = tmobi.user_id and tmobi.type = 'Mobi'

如果特定类型的记录不存在,请注意使用左外连接而不是内连接。您将在使用左外连接的结果集中获得这些列的空值。使用内部联接,您不会得到没有所有三种类型的用户的结果。祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 2013-10-01
    • 2018-05-30
    • 2016-03-02
    相关资源
    最近更新 更多