Databricks SQL读取多CSV文件跳过行异常问题求助
解决Databricks SQL中多CSV文件不同跳过行数合并问题
核心思路
无需分表再Union,直接通过对每个文件的行编号+条件过滤,统一处理不同文件的跳过行数,再映射到固定表头即可。
方案1:固定表头列时的简洁处理(推荐)
如果所有文件跳过对应行数后的列顺序、数量完全一致,且你明确知道表头列名,直接用以下语句:
CREATE TABLE merged_csv_table AS SELECT -- 手动映射列名,替换成你的实际表头 _c0 AS 订单ID, _c1 AS 客户名称, _c2 AS 订单金额, input_file_name() AS 源文件路径 -- 可选,用于追踪数据来源 FROM ( SELECT *, -- 按每个文件分组给行编号 row_number() OVER (PARTITION BY input_file_name() ORDER BY NULL) AS row_num FROM csv.`/dbfs/path/to/your/csv/files` -- 替换成你的文件路径 OPTIONS ( header = 'false', -- 不启用自动表头读取 inferSchema = 'false', -- 先按字符串读取,后续可调整schema delimiter = ',' -- 根据你的CSV分隔符修改,比如'\t' ) ) raw_data WHERE -- 针对特殊文件跳过前5行,其他文件跳过前4行 (input_file_name() LIKE '%特殊文件名.csv' AND row_num > 5) OR (input_file_name() NOT LIKE '%特殊文件名.csv' AND row_num > 4);
方案2:动态提取表头的通用处理
如果需要确保表头匹配(比如担心列顺序不一致),可以先提取每个文件的正确表头行,再将数据行与表头关联映射:
CREATE TABLE merged_csv_table AS WITH raw_csv AS ( SELECT input_file_name() AS file_path, *, row_number() OVER (PARTITION BY input_file_name() ORDER BY NULL) AS row_num FROM csv.`/dbfs/path/to/your/csv/files` OPTIONS (header='false', inferSchema='false', delimiter=',') ), -- 提取每个文件的正确表头行 header_rows AS ( SELECT file_path, -- 将表头列转为数组,方便后续映射 array(_c0, _c1, _c2) AS header_cols -- 替换成实际列数 FROM raw_csv WHERE (file_path LIKE '%特殊文件名.csv' AND row_num = 5) OR (file_path NOT LIKE '%特殊文件名.csv' AND row_num = 4) ), -- 提取每个文件的有效数据行 data_rows AS ( SELECT file_path, array(_c0, _c1, _c2) AS data_cols -- 替换成实际列数 FROM raw_csv WHERE (file_path LIKE '%特殊文件名.csv' AND row_num > 5) OR (file_path NOT LIKE '%特殊文件名.csv' AND row_num > 4) ), -- 将数据行与表头映射为键值对 mapped_data AS ( SELECT map_from_arrays(h.header_cols, d.data_cols) AS data_map FROM data_rows d JOIN header_rows h ON d.file_path = h.file_path ) -- 展开键值对为结构化列 SELECT data_map['订单ID'] AS 订单ID, data_map['客户名称'] AS 客户名称, data_map['订单金额'] AS 订单金额 FROM mapped_data;
注意事项
- 替换代码中的文件路径、特殊文件名、列名和分隔符为你的实际情况。
- 如果需要自动推断Schema,可以在最终SELECT时用
CAST(data_map['订单金额'] AS DECIMAL(10,2))这类语句转换数据类型。 row_number() OVER (PARTITION BY input_file_name() ORDER BY NULL)中的ORDER BY NULL是因为CSV行顺序固定,无需额外排序。
内容的提问来源于stack exchange,提问作者Greencolor
相关产品推荐
相关产品推荐

