我有一个具有以下结构的现有表
+-------------+-------+-------+-------+
| employee_id | val_1 | val_2 | val_3 | ...
+-------------+-------+-------+-------+
| 123 | A | B | C |
我想将此单个表更改为2个表 - 一个包含单独行中的值,另一个表成为此表的连接表。例如,以上内容将变为:
+-------------+--------+ +----+-------+
| employee_id | val_id | | id | value |
+-------------+--------+ +----+-------+
| 123 | 1 | | 1 | A |
+-------------+--------+ +----+-------+
| 123 | 2 | | 2 | B |
+-------------+--------+ +----+-------+
| 123 | 3 | | 3 | C |
+-------------+--------+ +----+-------+
用于将现有表格转换为这两个新表格的最佳SQL是什么?我可以很容易地创建值表,但我不确定如何在同一时间创建连接表。
答案 0 :(得分:1)
这样的事情(仅限伪造的代码,对不起):
For each row in (SELECT employee_id, val_1, val_2, val_3 FROM existing_table)
{
for each val in (row.Values)
{
INSERT INTO new_values (val)
val_id = SELECT LAST_INSERT_ID();
INSERT INTO new_employees (employee_id, val_id);
}
}
可能有一种基于集合的方法来避免循环......但很抱歉,我不知道它是什么样的,我不知道如何获取值表的身份进入父雇员表。
而且,虽然cursors通常不受欢迎,但这种一次性操作正是他们的设计目标(即我不建议使用游标进行常规交易或报告处理,但对于重新构建数据....为什么不呢?)。
答案 1 :(得分:0)
第一个结果
`INSERT INTO new_val
SELECT emp_id, REPLACE(UPPER(column_name), 'VAL_', '') FROM
information_schema.COLUMNS ,
employee
WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'myschema' AND column_name LIKE 'VAL_%'`;
使用第一个结果,填充查询并使用它插入新表;
可能需要进行微调。没有测试过
SELECT CONCAT('select ', new_val.number, ', VAL_', new_val.number, '
FROM employee, new_val
WHERE new_val.emp_id = employee.emp_id and new_val.number = ', val.number,
' union all' ) FROM
val ;
答案 2 :(得分:0)
所以这就是我最后编写的内容。正如程序名称所示,我期待有一种更简单的方法来做到这一点!
CREATE PROCEDURE iWasHopingItWouldBeSimpler()
BEGIN
DECLARE loop_done BOOLEAN DEFAULT 0;
DECLARE emp_id BIGINT(20);
DECLARE val1 DECIMAL(19,2);
DECLARE val2 DECIMAL(19,2);
DECLARE val3 DECIMAL(19,2);
DECLARE emp CURSOR
FOR
SELECT employee_id, val1, val2, val3 FROM existing;
-- Declare continue handler
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET loop_done=1;
OPEN emp;
-- Loop through all rows
REPEAT
FETCH emp INTO emp_id, val1, val2, val3;
INSERT INTO new_values (value) VALUES(val1);
INSERT INTO new_join (employee_id, values_id) VALUES(emp_id, LAST_INSERT_ID());
INSERT INTO new_values (value) VALUES(val2);
INSERT INTO new_join (employee_id, values_id) VALUES(emp_id, LAST_INSERT_ID());
INSERT INTO new_values (value) VALUES(val3);
INSERT INTO new_join (employee_id, values_id) VALUES(emp_id, LAST_INSERT_ID());
-- End of loop
UNTIL loop_done END REPEAT;
CLOSE emp;
SET loop_done=0;
END;