1

最初の正規形に到達するために、古い MySQL テーブルから BLOB を取り出して新しいテーブルを作成しようとしています。ただし、データベースに既に存在するデータを BLOB から新しいテーブルの複数の行に変換するのは簡単なことではありません。

SQL コマンドで変換を行う最も簡単な方法は何ですか?

親テーブル:

CREATE  TABLE TEST.People (
  `id` INT  AUTO_INCREMENT,
  `age` INT,
  `height` INT,
  `weight` INT  ,
  `variations` BLOB DEFAULT NULL,
  PRIMARY KEY (`id`), 
);

新しいテーブル:

CREATE  TABLE TEST.Variations (
  `id` INT  AUTO_INCREMENT,
  `chr` INT,
  `start` INT,
  `stop` INT  ,
  `type` ENUM('SNP','INDEL','CNV') DEFAULT NULL,
  PRIMARY KEY (`id`), 
);

SELECT id,variations FROM TEST.People; を実行すると、私は得る:

+----+----------------------------------------------------------------------------------------------------------------------+
| id | variations                                                                                                           |
+----+----------------------------------------------------------------------------------------------------------------------+
|  3 | xp   t !3:124093754-124467278/CNVt 7:78030601-79638023/CNV                                                           |
|  6 | xp                                                                                                                   |
|  9 | xp                                                                                                                   |
| 12 | xp   t !1:84289718-85466763/CNV                                                                                      |
| 15 | xp                                                                                                                   |
| 18 | xp                                                                                                                   |
| 21 | xp                                                                                                                   |
| 24 | xp                                                                                                                   |
| 27 | xp                                                                                                                   |
| 30 | xp   t !10:166909544-166909544/SNPt !2:66903445-66903445/SNPt !2:166897864-166897864/CNVt !7:6892788-6892788/SNP     |
+----+----------------------------------------------------------------------------------------------------------------------+

したがって、変換後に TEST.Variations テーブルに持たせたいのは次のとおりです。

+----+-----+-----------+-----------+----------+
| id | chr | start     | stop      | type     |  
+----+-----+-----------+-----------+----------+
|  3 |   3 | 124093754 | 124467278 | CNV      |
|  3 |   7 |  78030601 |  79638023 | CNV      |
| 12 |   1 |  84289718 |  85466763 | CNV      |
| 30 |  10 | 166909544 | 166909544 | SNP      |
| 30 |   2 |  66903445 |  66903445 | SNP      |
| 30 |   2 | 166897864 | 166897864 | CNV      |
| 30 |   7 |   6892788 |   6892788 | SNP      |
+----+-----+-----------+-----------+----------+
4

1 に答える 1

1

まず、次の2 つのことを行います。

  1. ID 3 のデータに矛盾があります。 の!前に権利がありません7:...。それが単なるタイプミスであることを願っています

    xp   t !3:124093754-124467278/CNVt 7:78030601-79638023/CNV
                                      ^^
    
  2. ターゲットテーブルに列が必要な場合auto_increment、スキーマは次のようになります

    CREATE  TABLE variations 
    (
      `var_id` INT NOT NULL AUTO_INCREMENT,
      `id`    INT, -- id from People goes here and it's not UNIQUE
      `chr`   INT,
      `start` INT,
      `stop`  INT ,
      `type`  ENUM('SNP','INDEL','CNV') DEFAULT NULL,
      PRIMARY KEY (`var_id`) 
    );
    

クエリを使用しPeopleてテーブルからデータを転送できるようになりましたVariations

INSERT INTO variations (id, chr, start, stop, type)
SELECT id, 
       SUBSTRING_INDEX(variation, ':', 1) chr,
       SUBSTRING_INDEX(SUBSTRING_INDEX(variation, '-', 1), ':', -1) start,
       SUBSTRING_INDEX(SUBSTRING_INDEX(variation, '-', -1), '/', 1) stop,
       SUBSTRING_INDEX(variation, '/', -1) type
  FROM
(
  SELECT p.id, SUBSTRING_INDEX(SUBSTRING_INDEX(p.variations, 't !', n.n), 't !', -1) variation
    FROM 
  (
    SELECT id, SUBSTR(variations, 9) variations
      FROM people 
     WHERE variations LIKE 'xp   t !%'
  ) p CROSS JOIN 
  (
     SELECT a.N + b.N * 10 + 1 n
       FROM 
      (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
     ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
      ORDER BY n
  ) n
   WHERE n.n <= 1 + (LENGTH(p.variations) - LENGTH(REPLACE(p.variations, 't !', ''))) / 3
   ORDER BY id
) q
 ORDER BY id, chr, start, stop, type;

注:このクエリは、 id ごとに最大 100 のバリエーション に分割されます。多かれ少なかれ必要な場合は、nエイリアスを使用して内部サブクエリを編集することで制限を調整できます。これにより、その場で数値 (集計) テーブルが生成されます。

結果:

| | VAR_ID | ID | CHR | スタート | 停止 | タイプ |
|--------|----|-----|-----------|-----------|----- -|
| | 1 | 3 | 3 | 124093754 | 124467278 | CNV |
| | 2 | 3 | 7 | 78030601 | 79638023 | CNV |
| | 3 | 12 | 1 | 84289718 | 85466763 | CNV |
| | 4 | 30 | 10 | 166909544 | 166909544 | SNP |
| | 5 | 30 | 2 | 166897864 | 166897864 | CNV |
| | 6 | 30 | 2 | 66903445 | 66903445 | SNP |
| | 7 | 30 | 7 | 6892788 | 6892788 | SNP |

これがSQLFiddleのデモです

于 2013-09-12T00:53:24.087 に答える