如何在HeidiSQL中导入列数不等的CSV并拆分至关联SQL表
导入行列数不等的CSV到SQL数据库(主表+子表)
1. 先创建数据库表结构
在HeidiSQL中创建主表与子表,明确关联关系:
主表示例
假设主表存储CSV每行的固定基础数据,以自增ID为主键,Classnr作为与子表关联的字段:
CREATE TABLE main_table ( main_id INT AUTO_INCREMENT PRIMARY KEY, -- 替换为你的CSV中固定存在的其他字段,如名称、时间等 Classnr VARCHAR(50) NOT NULL );
子表示例
子表存储Class相关的详细字段,通过Classnr关联主表:
CREATE TABLE class_subtable ( sub_id INT AUTO_INCREMENT PRIMARY KEY, Classnr VARCHAR(50) NOT NULL, Class_pts INT, class_ptsrati DECIMAL(10,2), class_meandist DECIMAL(10,2), Density DECIMAL(10,2), FOREIGN KEY (Classnr) REFERENCES main_table(Classnr) );
2. 预处理CSV文件(推荐,适配大数量数据)
如果CSV的可变部分是重复的Class字段组(每组包含Classnr、Class_pts、class_ptsrati、class_meandist、Density5个字段),可以用Python脚本拆分数据,生成结构规整的两个CSV:
import csv # 替换为你的CSV文件路径 input_file = "your_raw_data.csv" main_output = "main_data.csv" sub_output = "sub_data.csv" # 根据你的CSV调整:主表固定列数、子表每组字段数 MAIN_COL_COUNT = 2 # 假设前2列是主表固定数据 SUB_GROUP_SIZE = 5 # 每个Class组包含5个字段 with open(input_file, 'r', encoding='utf-8') as infile, \ open(main_output, 'w', newline='', encoding='utf-8') as main_f, \ open(sub_output, 'w', newline='', encoding='utf-8') as sub_f: main_writer = csv.writer(main_f, delimiter=';') sub_writer = csv.writer(sub_f, delimiter=';') for row in csv.reader(infile, delimiter=';'): # 提取主表数据 main_writer.writerow(row[:MAIN_COL_COUNT]) # 拆分并提取子表数据 sub_groups = [row[i:i+SUB_GROUP_SIZE] for i in range(MAIN_COL_COUNT, len(row), SUB_GROUP_SIZE)] for group in sub_groups: if len(group) == SUB_GROUP_SIZE: sub_writer.writerow(group)
运行脚本后,会得到列数固定的main_data.csv(主表数据)和sub_data.csv(子表数据)。
3. 用HeidiSQL导入规整后的CSV
- 导入主表:连接数据库,右键
main_table→ 导入CSV数据,选择main_data.csv,分隔符选分号,匹配字段对应关系后完成导入。 - 导入子表:重复上述操作,选择
sub_data.csv导入class_subtable即可。
4. 无脚本直接用HeidiSQL处理(适合小数据量)
如果数据量不大,可先将整行CSV导入临时表,再用SQL拆分:
- 创建临时表:
CREATE TABLE temp_csv ( row_data TEXT NOT NULL );
- 在HeidiSQL中导入原始CSV到
temp_csv,将每行作为字符串存入row_data字段。 - 拆分数据插入主表(假设主表取前2列,
Classnr为第二列):
INSERT INTO main_table (字段1, Classnr) SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(row_data, ';', 1), ';', -1) AS 字段1, SUBSTRING_INDEX(SUBSTRING_INDEX(row_data, ';', 2), ';', -1) AS Classnr FROM temp_csv;
- 拆分数据插入子表(假设主表列数为2,子表每组5字段,最多10组,可按需调整数字序列):
INSERT INTO class_subtable (Classnr, Class_pts, class_ptsrati, class_meandist, Density) SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.row_data, ';', 2 + (n.num * 5) + 1), ';', -1) AS Classnr, SUBSTRING_INDEX(SUBSTRING_INDEX(t.row_data, ';', 2 + (n.num * 5) + 2), ';', -1) AS Class_pts, SUBSTRING_INDEX(SUBSTRING_INDEX(t.row_data, ';', 2 + (n.num * 5) + 3), ';', -1) AS class_ptsrati, SUBSTRING_INDEX(SUBSTRING_INDEX(t.row_data, ';', 2 + (n.num * 5) + 4), ';', -1) AS class_meandist, SUBSTRING_INDEX(SUBSTRING_INDEX(t.row_data, ';', 2 + (n.num * 5) + 5), ';', -1) AS Density FROM temp_csv t JOIN ( SELECT 0 AS num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) n ON 2 + (n.num * 5) + 5 <= LENGTH(t.row_data) - LENGTH(REPLACE(t.row_data, ';', '')) + 1;
- 删除临时表:
DROP TABLE temp_csv;
内容的提问来源于stack exchange,提问作者Zurch
相关产品推荐
相关产品推荐

