MySQL需要帮助将垂直数据重新格式化为水平

Posted

技术标签:

【中文标题】MySQL需要帮助将垂直数据重新格式化为水平【英文标题】:MySQL Need Help reformatting vertical data to horizontal 【发布时间】:2014-07-07 20:07:43 【问题描述】:

目前数据库如下所示:(产品 ID 与名称值对)

id、attribute_name、attribute_value 1,时钟速度,1.6Ghz 1,屏幕,13.3" 2,时钟速度,1.8Ghz 2、屏幕,15.1"


我想将以上数据转换为以下格式(以产品ID分隔,每个ID只有一行)以迁移到新平台。

id、时钟速度、屏幕 1、1.6Ghz、13.3" 2、1.8Ghz、15.1"

实现此结果的最简单方法是什么?我的直觉告诉我,这将通过 concat 或 group_concat 函数完成,但我需要一个正确的方向,因为拔头发会秃顶。

【问题讨论】:

【参考方案1】:

这指出了entity-attribute-value 数据库设计的问题之一。

有两种方法可以使用 SQL 将属性转换为列,就像您将数据存储在常规表中一样:

SELECT id, MAX(CASE attribute_name WHEN 'Clockspeed' THEN attribute_value END) AS Clockspeed,
  MAX(CASE attribute_name WHEN 'Screen' THEN attribute_value END) AS Screen
FROM eav_table
GROUP BY id;

SELECT id, c.attribute_value AS Clockspeed, s.attribute_value AS Screen
FROM eav_table AS c
JOIN eav_table AS s USING(id)
WHERE c.attribute_name = 'Clockspeed' AND s.attribute_name = 'Screen'

mysql 5.6 上测试后两个查询的输出:

+------+------------+--------+
| id   | Clockspeed | Screen |
+------+------------+--------+
|    1 | 1.6GHz     | 13.3"  |
|    2 | 1.8GHz     | 15.1"  |
+------+------------+--------+

后一种解决方案需要 N-1 个连接来输出 N 个属性。它不能很好地扩展。

上述两种解决方案都要求您根据要获取的属性数量编写相当多的应用程序代码来格式化 SQL 查询。这意味着如果属性的数量不同(这可能是因为这是使用 EAV 的主要优势之一),则可能会获取太多属性以使查询具有良好的性能。

另一种解决方案是忘记仅使用 SQL 对数据进行透视。相反,将数据库的行获取到您的应用程序每行一个属性,因为它们存储在数据库中。然后编写应用程序代码,将结果后处理成一个对象。

【讨论】:

尽管这看起来很光彩,但我担心它是在我头上的嗖嗖声,。我试图运行它来咯咯地笑,但遇到了语法错误。 (当然是在换掉“eav_table”之后) 好的,我已经测试了两个查询并修正了一个错字。 你先生,是个巫师。

以上是关于MySQL需要帮助将垂直数据重新格式化为水平的主要内容,如果未能解决你的问题,请参考以下文章

格式化的 Mysql JSON 与在后端重新格式化为 JSON

将列表格式化为列的理想方法是啥,它们在垂直方向上保持字母顺序?

如何将文本重新格式化为不同的模式?

将一列字符串重新格式化为两个 [关闭]

将同步代码重新格式化为异步

将文本文件重新格式化为一行字符串[重复]