MySQL 从 CSV 数据加载 NULL 值
Posted
技术标签:
【中文标题】MySQL 从 CSV 数据加载 NULL 值【英文标题】:MySQL load NULL values from CSV data 【发布时间】:2011-02-10 03:29:15 【问题描述】:我有一个文件,其中可以包含 3 到 4 列用逗号分隔的数值。空字段在行尾时除外:
1,2,3,4,5
1,2,3,,5
1,2,3
在 mysql 中创建了下表:
+-------+--------+------+------+---------+--------+ |领域 |类型 |空 |钥匙 |默认 |额外 | +-------+--------+------+------+---------+--------+ |一个 |整数(1) |是 | |空 | | |二 |整数(1) |是 | |空 | | |三 |整数(1) |是 | |空 | | |四 |整数(1) |是 | |空 | | |五 |整数(1) |是 | |空 | | +-------+--------+------+------+---------+--------+我正在尝试使用 MySQL LOAD 命令加载数据:
LOAD DATA INFILE '/tmp/testdata.txt' INTO TABLE moo FIELDS
TERMINATED BY "," LINES TERMINATED BY "\n";
结果表:
+------+------+--------+------+------+ |一个 |二 |三 |四 |五 | +------+------+--------+------+------+ | 1 | 2 | 3 | 4 | 5 | | 1 | 2 | 3 | 0 | 5 | | 1 | 2 | 3 |空 |空 | +------+------+--------+------+------+问题在于,当原始数据中的字段为空且未定义时,MySQL 出于某种原因不使用列默认值(即 NULL)并使用零。当字段全部丢失时正确使用NULL。
不幸的是,在这个阶段我必须能够区分 NULL 和 0,因此我们将不胜感激。
谢谢 S.
编辑
显示警告的输出:
+---------+------+-------------------------------- ------------------------------------+ |水平 |代码 |留言 | +---------+------+-------------------------------- ------------------------------------+ |警告 |第1366章不正确的整数值:第 2 行的列 'four' 的 '' | |警告 |第1261章第 3 行不包含所有列的数据 | |警告 |第1261章第 3 行不包含所有列的数据 | +---------+------+-------------------------------- ------------------------------------+【问题讨论】:
随着数据模式的改变,我会使用d6tstack,它会在运行LOAD DATA
之前对齐所有列。请参阅 d6tstack SQL examples 有关数据架构更改的部分。
【参考方案1】:
预处理您的输入 CSV 以将空白条目替换为 \N。
尝试正则表达式:s/,,/,\n,/g 和 s/,$/,\N/g
祝你好运。
【讨论】:
这个正则表达式部分有效,它不能解决连续的空白条目,例如 ,,,, will be ,\n,,\n, 如果你运行两次应该可以使用 会总结答案和之前的评论。以下为我工作,按顺序: sed -i 's/,,/,\N/g' $file, sed -i 's/,,/,/g' $file, sed -i 's/\ N,$/\N/g' $文件, 我想这样做,但我不清楚你是如何运行这个正则表达式的。如果您使用 MySQL 对文件运行它,这将是最好的解决方案。但是你不说,我也不想花很多时间在谷歌上搜索如何做一些不可能的事情。【参考方案2】:MySQL manual 说:
使用 LOAD DATA 读取数据时 INFILE,空或缺失的列是 用''更新。如果你想要一个 NULL 列中的值,您应该使用 \N 在数据文件中。字面意思 在某些情况下也可以使用“NULL” 情况。
所以你需要像这样用 \N 替换空格:
1,2,3,4,5
1,2,3,\N,5
1,2,3
【讨论】:
感谢您的提示 - 我对编辑原始源数据持怀疑态度,但如果这是解决它的唯一方法,我会尝试一下。 我理解你的怀疑,没有人喜欢编辑原始数据,只是感觉不对。但是,如果您考虑一下,必须有一种方法可以区分 NULL 和空字符串。如果将空白条目转换为 NULL,则需要一个特殊的空字符串序列。很高兴有一种方法告诉 MySQL 如何处理空白条目,例如 LOAD DATA INFILE '/tmp/testdata.txt' INTO TABLE moo TREAT BLANKS AS NULL... 好的,但是如果你有Fields enclosed by: "
是"\N"
的"name",\N,"stuff"
我可以验证至少对于“phpMyAdmin 3.5.5”没有\N
的样式被接受为表示NULL
。请改用NULL
,如本例所示:"name","age",NULL,"other","stuff"
我们有 MySQL 5.5.46-0+deb8u1。我尝试了 NULL 和 \N,只有 \N 对我们有用。【参考方案3】:
这会做你想做的事。它将第四个字段读入局部变量,然后将实际字段值设置为 NULL,如果局部变量最终包含一个空字符串:
LOAD DATA INFILE '/tmp/testdata.txt'
INTO TABLE moo
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
(one, two, three, @vfour, five)
SET four = NULLIF(@vfour,'')
;
如果它们都可能是空的,那么你会将它们全部读入变量并拥有多个 SET 语句,如下所示:
LOAD DATA INFILE '/tmp/testdata.txt'
INTO TABLE moo
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
(@vone, @vtwo, @vthree, @vfour, @vfive)
SET
one = NULLIF(@vone,''),
two = NULLIF(@vtwo,''),
three = NULLIF(@vthree,''),
four = NULLIF(@vfour,'')
;
【讨论】:
理论上,我想 - 但它都在内存中,每行只保存少量数据,所以我认为它是无穷小的;但如果您认为这可能是一个问题,您应该对其进行测试。 我真的很喜欢这个答案。用户在为 excel 下载 csv(在SELECT INTO OUTFILE
查询中使用 IFNULL(Col,'')
)时可以看到空字符串 ''
,但随后上传接受它们为空,而不必处理 csv 中的 \N
。谢谢!
对于我使用的日期 'NULLIF(STR_TO_DATE(@date1, "%d/%m/%Y"), "0000-00-00")'
我有一个 csv 文件,其中包含零 0
应转换为 NULL
(因为所讨论的数据不可能有零值)以及空字符串。如何确保零和空字符串都转换为NULL
?
如果零值和空字符串在不同的列中,则只需对空字符串执行上述操作,对零执行类似操作:nullif(@vone, 0)
。【参考方案4】:
行为因数据库配置而异。在严格模式下,这会抛出错误,否则会发出警告。 以下查询可用于识别数据库配置。
mysql> show variables like 'sql_mode';
【讨论】:
谢谢!我正在摸不着头脑,试图弄清楚为什么我昨天在生产服务器上成功导入的带有空列的 CSV 在我全新的本地安装上不起作用——这就是我的答案!【参考方案5】:显示变量
Show variables like "`secure_file_priv`";
注意:将您的 csv 文件保存在上述命令给出的位置。
create table assessments (course_code varchar(5),batch_code varchar(7),id_assessment int, assessment_type varchar(10), date int , weight int);
注意:这里的 'date
' 列在 csv 文件中有一些空白值。
LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/assessments.csv'
INTO TABLE assessments
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY ''
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(course_code,batch_code,id_assessment,assessment_type,@date,weight)
SET date = IF(@date = '', NULL, @date);
【讨论】:
【参考方案6】:(变量 1,@变量 2,..) SET variable2 = nullif(@variable2, '' or ' ') >> 你可以放任何条件
【讨论】:
这可能会更好作为***.com/a/5968530/10376320的评论【参考方案7】:在 UNIX 终端中使用以下 sed 命令将输入文件转换为包含 \N
的空白列数据:
sed -i 's/,,/,\\N,/g' $file_name
然后使用LOAD DATA INFILE
命令加载到mysql
【讨论】:
以上是关于MySQL 从 CSV 数据加载 NULL 值的主要内容,如果未能解决你的问题,请参考以下文章
从 CSV NULL 值导入的 PostgreSQL 是文本 - 需要 null