4

説明

以下はテーブル構造です:

適格性表

ID     COURSE_ID     BRANCH_IDS
1      501           621,622,623
1      502
1      503           625
2      501           621
2      505           650
3      500

現在、以下のように新しいテーブル構造を作成し、eligibility_table を介して course_table、branch_table を挿入しています。したがって、次の最終出力が必要です

コーステーブル

ID COURSE_ID
1  501
1  502
1  503
2  501
2  505
3  500

branch_table

ID BRANCH_ID
1  621
1  622
1  623
1  625
2  621
2  650

問題:

branch_table の SQL QUERY を書くのに苦労しています。のようなクエリを書きたい

INSERT INTO branch_table SELECT --- from eligibility_table --
4

2 に答える 2

4

UPDATEDこのようなSQLでそれを行うことができます

INSERT INTO branch_table (id, branch_id)
SELECT e.id, SUBSTRING_INDEX(SUBSTRING_INDEX(e.branch_ids, ',', n.n), ',', -1) branch_id
  FROM eligibility_table e 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(e.branch_ids) - LENGTH(REPLACE(e.branch_ids, ',', '')))
 ORDER BY id, branch_id
  • UNION ALLn のエイリアスを持つサブクエリは、この特定のケースでは と を使用して、1 から 100 までの一連の数字 (数字または集計テーブル) をその場で生成しますCROSS JOINdb に実際の集計表があると便利な場合があります
  • 外側の select では、最も内側SUBSTRING_INDEX()のリストの n 番目の要素まですべてを取得しSUBSTRING_INDEX()、最後の区切り文字の直後に外側の抽出を行い、n 番目の要素自体を効果的に取得します。
  • CROSS JOINデカルト積である一連の行を作成できます (n の 100 行と eligibility_table のすべての行)。
  • WHERE句の条件は、結果セットからすべての不要な行を除外します

注: このクエリは、最大 100 のブランチ ID に分割されます。多かれ少なかれ必要な場合は、内側のサブクエリを編集して制限を調整できます

結果は branch_table になります:

| | ID | BRANCH_ID |
------------------
| | 1 | 621 |
| | 1 | 622 |
| | 1 | 623 |
| | 1 | 625 |
| | 2 | 621 |
| | 2 | 650 |

これがSQLFiddleのデモです

于 2013-06-24T08:46:33.637 に答える
3

If I'm correct in that you are changeing your database structure so it is actually normalized, and this is a one time thing, I'd suggest you do this in code. Connect to the database, read your old tables and insert the new. You can add some error-checking and exceptionhandling as well!

Just take your favorite language, and then do a standard split() on that comma-separated value, and insert those values in the table. If it doesn't work you can print out what line went wrong so you can manually fix those issues. (that will be much harder in sql to accomplish)

于 2013-06-24T06:51:59.710 に答える