使用MySQL将数据表从长到大重新格式化(重新整形)

时间:2012-03-02 03:12:15

标签: mysql reshape

MySQL的新手并尝试从R中携带一些东西。

我有一个包含两列的数据表,类似于以下内容,具有level-2 id和嵌套id:

level2id | nestedid |
1        | 1        |
1        | 2        |
1        | 3        |
2        | 1        |
2        | 2        |
...

我想在新表中使用MYSql重构数据,如下所示:

level2id | nestedid1 | nestedid2 | nestedid3 |
1        | 1         | 2         | 3         |
2        | 1         | 2         |           |
...

这样我以后可以执行连接以提取有关嵌套id的信息,以便为与level2 id相关的变量创建聚合值。在R中使用reshape来处理“时变”数据时要做的很简单,但找不到这种特定格式的明显解决方案(即数据没有根据列中的属性名称和属性值进行组织。提前感谢!

3 个答案:

答案 0 :(得分:0)

虽然你不能把它作为SELECT来实现,你可以使用插入来实现这一点,只有当主键ls level2id或你在该level2id上有一个唯一索引时它才有效

表格结构

CREATE TABLE `table2` (
  `level2id` int(11) NOT NULL DEFAULT '0',
  `nestedid1` int(11) NOT NULL,
  `nestedid2` int(11) NOT NULL,
  `nestedid3` int(11) NOT NULL,
  PRIMARY KEY (`level2id`)
) ENGINE=InnoDB;

插入SQL语句将table1替换为旧表

INSERT INTO table2 (level2id, nestedid1) SELECT level2id, nestedid FROM table1 WHERE nestedid = 1 ON DUPLICATE KEY UPDATE nestedid1 = nestedid;
INSERT INTO table2 (level2id, nestedid2) SELECT level2id, nestedid FROM table1 WHERE nestedid = 2 ON DUPLICATE KEY UPDATE nestedid2 = nestedid;
INSERT INTO table2 (level2id, nestedid3) SELECT level2id, nestedid FROM table1 WHERE nestedid = 3 ON DUPLICATE KEY UPDATE nestedid3 = nestedid;

ON DUPLICATE KEY UPDATE是MySQL扩展更多细节http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

答案 1 :(得分:0)

我有类似的问题。 也许你想看一下sql中的动态旋转。 Dynamic pivot table with multiple columns in sql server。但是我真的不建议你是否可以在R中使用重塑命令。

答案 2 :(得分:0)

您可以使用MySQL创建一个可以解决此问题的MySQL程序:

USE test;

/*Create long input table 'test' with variables of varying length*/
DROP TABLE nums;
CREATE TABLE nums (id INT(2));
INSERT INTO nums
VALUES 
(0), (1), (2), (3), (4), (5), (6), (7);

DROP TABLE test;
CREATE TABLE test (id INT(2), var VARCHAR(5), attribute VARCHAR(6), PRIMARY KEY (id, var));
INSERT INTO test
SELECT nums3.*, REPEAT(CHAR(97+RAND()*24),CAST(6.*RAND() AS INT)) AS attribute
 FROM (SELECT DISTINCT nums2.id1 as id, CONCAT('var', LPAD(CAST(16.*RAND() AS INT),2,'0')) AS var  
 FROM (SELECT DISTINCT nums.id as id1, nums1.id as id2 FROM nums, nums as nums1) AS nums2) AS nums3;

/*Create SQL program to convert long to wide format (R: reshape)*/
SELECT DISTINCT CONCAT('DROP TABLE result;\nCREATE TABLE result (id INT(2),
', GROUP_CONCAT(CONCAT(field) SEPARATOR ', '), ');')
FROM 
(SELECT DISTINCT CONCAT(var, CONCAT(' VARCHAR(', max(length(attribute)), ')')) AS field
FROM test GROUP BY var) AS fields

UNION

SELECT CONCAT("INSERT INTO result \nSELECT DISTINCT test.id, ", GROUP_CONCAT(var SEPARATOR '.attribute, '),
".attribute FROM (SELECT DISTINCT id FROM test) AS test") 
FROM (SELECT DISTINCT var FROM test ORDER BY var) as vars

UNION

SELECT CONCAT("LEFT JOIN test AS ", var, " ON test.id = ", var, ".id AND ", var, ".var=", '"', var, '"' )
FROM (SELECT DISTINCT var FROM test ORDER BY var) as vars

UNION

SELECT ";" ;

/*Copy output to screen editor, delete '|' symbols and superfluous white spaces.
Then copy to MySQL prompt, run by pressing 'enter' key and view 'result'*/