如何在mysql中组合多行数据

时间:2015-04-15 11:42:39

标签: mysql stored-procedures

我试图将MySQL中的数据组合到视图或存储过程中,以便回写到新表或作为视图访问。我的数据库将客户元数据存储在具有键和值的单独行中。我很困惑如何以有用的形式提取这些数据。

我的数据以这种方式形成:

 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中使用。

我试图实施https://stackoverflow.com/a/5967720/3001841,但它对我来说没有意义。

简单地将数据放在一行对我来说很有用:

客户,订单,地址,名称,地址行1,地址行2,城市,地区,邮政代码,国家,电子邮件地址,数

1 个答案:

答案 0 :(得分:0)

这是一个使用视图以方便使用的示例,但如果需要,您也可以将视图查询烘焙到最终查询中。 (香港专业教育学院使用invoice你曾经使用过order,对不起。顺便说一下,尽量避免使用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;

我们按客户分组(您可能希望在where上添加invoice过滤器,然后我们可以使用max()来确保忽略所有null值,并仅获取包含有效数据的字段。

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