我有一张格式如下的表格。
mysql> describe unit_characteristics;
+----------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| uut_id | int(10) unsigned | NO | PRI | NULL | |
| uut_sn | varchar(45) | NO | | NULL | |
| characteristic_name | varchar(80) | NO | PRI | NULL | |
| characteristic_value | text | NO | | NULL | |
| creation_time | datetime | NO | | NULL | |
| last_modified_time | datetime | NO | | NULL | |
+----------------------+------------------+------+-----+---------+----------------+
每个uut_sn都有多个特征名称/值对。我想用MySQL来生成一个表
+----------------------+-------------+-------------+-------------+--------------+
| uut_sn | char_name_1 | char_name_2 | char_name_3 | char_name_4 | ... |
+----------------------+-------------+-------------+-------------+--------------+
| 00000 | char_val_1 | char_val_2 | char_val_3 | char_val_4 | ... |
| 00001 | char_val_1 | char_val_2 | char_val_3 | char_val_4 | ... |
| 00002 | char_val_1 | char_val_2 | char_val_3 | char_val_4 | ... |
| ..... | char_val_1 | char_val_2 | char_val_3 | char_val_4 | ... |
+----------------------+------------------+------+-----+---------+--------------+
只用一个查询就可以了吗?
谢谢, -Peter
答案 0 :(得分:3)
这是标准的透视查询:
SELECT uc.uut_sn,
MAX(CASE
WHEN uc.characteristic_name = 'char_name_1' THEN uc.characteristic_value
ELSE NULL
END) AS char_name_1,
MAX(CASE
WHEN uc.characteristic_name = 'char_name_2' THEN uc.characteristic_value
ELSE NULL
END) AS char_name_2,
MAX(CASE
WHEN uc.characteristic_name = 'char_name_3' THEN uc.characteristic_value
ELSE NULL
END) AS char_name_3,
FROM unit_characteristics uc
GROUP BY uc.uut_sn
要使其动态化,您需要使用MySQL's dynamic SQL syntax called Prepared Statements。它需要两个查询 - 第一个获取characteristic_name
值的列表,因此您可以将相应的字符串连接到CASE表达式中,就像您在我的示例中看到的最终查询一样。
答案 1 :(得分:1)
您正在使用EAV反模式。无法自动生成您描述的数据透视表,无需对要包含的特征进行硬编码。正如@OMG Ponies所提到的那样,您需要使用动态SQL以自定义方式对查询进行通用,以获得要包含在结果中的特征集。
相反,我建议您每行获取一个特征,因为它们存储在数据库中,如果您希望应用程序对象代表具有其所有特征的单个UUT,您可以编写代码来循环遍历行在您的应用程序中获取它们,将它们收集到对象中。
例如在PHP中:
$sql = "SELECT uut_sn, characteristic_name, characteristic_value
FROM unit_characteristics";
$stmt = $pdo->query($sql);
$objects = array();
while ($row = $stmt->fetch()) {
if (!isset($objects[ $row["uut_sn"] ])) {
$object[ $row["uut_sn"] ] = new Uut();
}
$objects[ $row["uut_sn"] ]->$row["characteristic_name"]
= $row["characterstic_value"];
}
与查询中的硬编码特征名称解决方案相比,这有一些优势: