当前位置: 首页 > 面试题库 >

将多行合并为一行MySQL

潘哲
2023-03-14
问题内容

假设我在MySQL数据库中有两个表。

表格1:

ID    Name
1     Jim
2     Bob
3     John

表2:

ID    key           value
1     address       "X Street"
1     city          "NY"
1     region        "NY"
1     country       "USA"
1     postal_code   ""
1     phone         "123456789"

数据库中选择行时,是否有任何方法可以将第二个表中的行作为列连接到第一个表中?

直接从MySQL查询获得的期望结果是:

ID    Name    address    city    region   country   postal_code   phone
1     Jim     X Street   NY      NY       USA       NULL          123456789
2     Bob     NULL       NULL    NULL     NULL      NULL          NULL
3     John    NULL       NULL    NULL     NULL      NULL          NULL

谢谢你的帮助!


问题答案:

这种数据转换类型称为PIVOT。MySQL没有枢轴函数,但是您可以使用带有CASE表达式的聚合函数来复制它:

select t1.id,
  t1.name,
  max(case when t2.`key` = 'address' then t2.value end) address,
  max(case when t2.`key` = 'city' then t2.value end) city,
  max(case when t2.`key` = 'region' then t2.value end) region,
  max(case when t2.`key` = 'country' then t2.value end) country,
  max(case when t2.`key` = 'postal_code' then t2.value end) postal_code,
  max(case when t2.`key` = 'phone' then t2.value end) phone
from table1 t1
left join table2 t2
  on t1.id = t2.id
group by t1.id, t1.name

请参阅带有演示的SQL Fiddle。

这也可以使用您的多个联接来编写,table2并且您将在每个联接的联接上包括一个过滤器key

select t1.id,
  t1.name,
  t2a.value address,
  t2c.value city,
  t2r.value region,
  t2y.value country,
  t2pc.value postal_code,
  t2p.value phone
from table1 t1
left join table2 t2a
  on t1.id = t2a.id
  and t2a.`key` = 'address'
left join table2 t2c
  on t1.id = t2c.id
  and t2c.`key` = 'city' 
left join table2 t2r
  on t1.id = t2r.id
  and t2c.`key` = 'region' 
left join table2 t2y
  on t1.id = t2y.id
  and t2c.`key` = 'country' 
left join table2 t2pc
  on t1.id = t2pc.id
  and t2pc.`key` = 'postal_code' 
left join table2 t2p
  on t1.id = t2p.id
  and t2p.`key` = 'phone';

请参阅带有演示的SQL Fiddle。

如果key值的数量有限,则上述两个版本将非常有用。如果您有未知数量的值,那么您将需要查看使用准备好的语句来生成动态SQL:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when t2.`key` = ''',
      `key`,
      ''' then t2.value end) AS `',
      `key`, '`'
    )
  ) INTO @sql
from Table2;

SET @sql 
    = CONCAT('SELECT t1.id, t1.name, ', @sql, ' 
              from table1 t1
              left join table2 t2
                on t1.id = t2.id
              group by t1.id, t1.name;');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

参见带有演示的SQL Fiddle

所有版本都会给出结果:

| ID | NAME |  ADDRESS |   CITY | REGION | COUNTRY | POSTAL_CODE |     PHONE |
|----|------|----------|--------|--------|---------|-------------|-----------|
|  1 |  Jim | X Street |     NY | (null) |  (null) |      (null) | 123456789 |
|  2 |  Bob |   (null) | (null) | (null) |  (null) |      (null) |    (null) |
|  3 | John |   (null) | (null) | (null) |  (null) |      (null) |    (null) |


 类似资料:
  • 问题内容: 我正在尝试不同的JOIN查询,但没有得到想要的结果。 我有2张桌子: 我找不到想要的结果。 我想得到以下结果: 问题答案: 您不能具有这样的动态列数,但是可以 将数据连接 成字符串: 或者您可以使用或手动 旋转行( 我更喜欢后一种方法,对我来说似乎更灵活,但是在某些情况下可以大大减少代码量): 您还可以将前面的语句转换为 动态SQL, 如下所示:

  • 问题内容: 我们有些SQL杂语。说我有一个看起来像这样的结果… 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | A 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | B 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | C 61E77D90-D53D-4E2E-A09E-9D6F012EB59C | D 7ce9

  • 问题内容: 我正在使用SQL Server2008。我具有下表中的数据: 我想以这种格式获取数据: 我怎样才能做到这一点? 问题答案: 使用PIVOT您可以执行以下操作 产生 查看有效的Data.SE示例 在不支持PIVOT的数据库中,您可以改为对表进行多次联接。尽管您可能还是想这样做,但是正如GBN所指出的那样,因为我们没有使用聚合。 查看有效的Data.SE示例

  • 问题内容: 我需要一些有关SUM功能的帮助。我试图将同一帐户的帐单金额相加为一个总计,但是我得到的结果显示我的SUM列只是我的第一列的3倍。 这是我想要的模拟数据结果: 询问: 或者 如果可能,我希望同时获得两个结果。 这是我得到的: 我的SUM列只是乘以三,实际上并没有基于帐号对数据求和。 问题答案: 谢谢你的回复。原来我的问题是重复条目的数据库问题,而不是我的逻辑。快速表同步修复了该问题,并且

  • 本文向大家介绍mysql如何将多行数据合并成一行,包括了mysql如何将多行数据合并成一行的使用技巧和注意事项,需要的朋友参考一下

  • 问题内容: 我需要将多行合并为单行,这将是简单的带有空间的连接 我希望数据帧像这样转换:(空格分隔)tempx值 我试过的 这行得通,但是它将所有列中的行合并在一起,如下所示: 有什么优雅的解决方案吗? 问题答案: 您可以使用和功能: