如何在 mysql 中合并多行数据

How to combine data in multiple rows in mysql

我正在尝试将 MySQL 中的数据合并到视图或存储过程中,以写回新的 table 或作为视图访问。我的数据库将客户元数据存储在单独的一行中,其中包含键和值。我对如何以有用的形式提取这些数据感到困惑。

我的数据是这样形成的:

 id order       customer    type        key               value
1   42FF86A1    45858007    shipping    address-name      David Customer
2   42FF86A1    45858007    shipping    email-address     david@email.com
3   42FF86A1    45858007    shipping    number            2125551212
4   42FF86A1    45858007    shipping    address-line1     5353 My Street
5   42FF86A1    45858007    shipping    address-line2     #2
6   42FF86A1    45858007    shipping    city              MyCity
7   42FF86A1    45858007    shipping    region            CA
8   42FF86A1    45858007    shipping    postal-code       95555
9   42FF86A1    45858007    shipping    country           US

最终我希望能够读取数据并将其轻松导出以用于我的 CRM 或 Excel。

我已经尝试实施 ,但对我来说如何实施没有意义。

简单地获取一行中的数据对我很有用,其中:

客户、订单、地址名称、地址行 1、地址行 2、城市、地区、邮政编码、国家、电子邮件地址、号码

为了方便起见,这里有一个使用视图的示例,但如果需要,您也可以将视图查询合并到最终查询中。 (我在您使用 order 的地方使用了 invoice,抱歉。顺便说一下,尽量避免使用 mysql 保留字作为字段名称,这很痛苦,必须记住对所有内容进行反引号。)

create view order_pivot as (
  select customer,  invoice, type, 
  case when `key` = 'address-name' then `value` end as address,
  case when `key` = 'email-address' then `value` end as email,
  case when `key` = 'number' then `value` end as number,
  case when `key` = 'address-line1' then `value` end as addressline1,
  case when `key` = 'address-line2' then `value` end as addressline2,
  case when `key` = 'city' then `value` end as city,
  case when `key` = 'region' then `value` end as region,
  case when `key` = 'postal-code' then `value` end as postalcode,
  case when `key` = 'country' then `value` end as country
  from orders
);

视图将数据转换成行,其中的列与我们感兴趣的列数相匹配。它不是很灵活,因为它需要您对这些关键字段进行硬编码,但它确实有效。它为我们提供了一个值,每一行都有一大堆空值——所以显然我们需要将它们全部合并到一行中,这就是下一个查询的来源。

select customer, max(address) addr, max(email) email, max(number) number, max(addressline1) a1, max(addressline2) a2, max(city) city, max(region) region, max(postalcode) postcode, max(country) country
  from order_pivot
  group by customer;

我们按客户分组(您可能还想在 invoice 上放置一个 where 过滤器,然后我们可以使用 max() 来确保我们忽略所有空值,并仅获取具有有效数据的字段。

here's a fiddle

编辑

合并这两个查询,因为您似乎没有查看权限:

select customer, max(address) addr, max(email) email, max(number) number, max(addressline1) a1, max(addressline2) a2, max(city) city, max(region) region, max(postalcode) postcode, max(country) country
  from (
  select customer,  invoice, type, 
  case when `key` = 'address-name' then `value` end as address,
  case when `key` = 'email-address' then `value` end as email,
  case when `key` = 'number' then `value` end as number,
  case when `key` = 'address-line1' then `value` end as addressline1,
  case when `key` = 'address-line2' then `value` end as addressline2,
  case when `key` = 'city' then `value` end as city,
  case when `key` = 'region' then `value` end as region,
  case when `key` = 'postal-code' then `value` end as postalcode,
  case when `key` = 'country' then `value` end as country
  from orders
) q
  group by customer;

updated fiddle with combined query