1

次の構造の既存のテーブルがあります

+-------------+-------+-------+-------+
| employee_id | val_1 | val_2 | val_3 | ...
+-------------+-------+-------+-------+
|         123 |     A |     B |     C |

この単一のテーブルを2つのテーブルに変更したいと思います。1つは別々の行の値を含み、もう1つはこのための結合テーブルになります。たとえば、上記は次のようになります。

+-------------+--------+      +----+-------+
| employee_id | val_id |      | id | value |
+-------------+--------+      +----+-------+
|         123 |      1 |      |  1 |     A |
+-------------+--------+      +----+-------+
|         123 |      2 |      |  2 |     B |
+-------------+--------+      +----+-------+
|         123 |      3 |      |  3 |     C |
+-------------+--------+      +----+-------+

既存のテーブルをこれらの2つの新しいテーブルに変換するために使用するのに最適なSQLは何ですか?値テーブルは簡単に作成できますが、同時に結合テーブルを作成する方法がわかりません。

4

3 に答える 3

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);
  }
}

ループを回避するためにこれを行うにはおそらくセットベースの方法があります...しかし、申し訳ありませんが、あなたのようにそれがどのようなものかわかりません。値テーブルのIDを親に戻す方法がわかりません従業員テーブル。

また、カーソルは一般的に嫌われていますが、この種の1回限りの操作は、まさにそれらが設計されたものです(つまり、通常のトランザクションやレポート処理にはカーソルをお勧めしませんが、データの再構築にはお勧めしません。 .. なぜだめですか?)。

于 2012-12-24T07:41:09.467 に答える
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 ;

于 2012-12-24T07:40:56.243 に答える
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;
于 2012-12-24T09:14:17.963 に答える