描述
以下是表结构:
eligibility_table
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。所以关注,我想要的最终输出
course_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 --
答案 0 :(得分:4)
更新您可以像这样使用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 ALL
和CROSS JOIN
,别名为n的子查询会动态生成1到100之间的数字序列(数字或计数表)。 有时在db 中有一个真正的计数表是很方便的。SUBSTRING_INDEX()
获取列表中第n个元素的所有内容,并且在最后一个分隔符后有效地获取第n个元素本身的外部SUBSTRING_INDEX()
提取最右边。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 演示
答案 1 :(得分:3)
如果我是正确的,你正在改变你的数据库结构,所以它实际上是规范化的,这是一次性的事情,我建议你在代码中这样做。连接到数据库,读取旧表并插入新表。您也可以添加一些错误检查和异常处理!
只需使用您喜欢的语言,然后对该逗号分隔值执行标准split()
,并在表格中插入这些值。如果它不起作用,您可以打印出错误的行,以便您可以手动修复这些问题。 (这将在sql中更难实现)