mysqldump带SELECT子查询的WHERE条件无数据输出问题
解决mysqldump带子查询WHERE条件仅导出表结构的问题
我之前也踩过mysqldump子查询的坑,你的情况大概率是shell对引号和括号的解析逻辑搞的鬼,让我给你拆解原因和解决办法:
问题根源
当你在shell命令行里直接使用包含子查询的--where参数时,shell会把括号、双引号这类字符当作自身的语法符号去解析,而不是完整传递给mysqldump和MySQL。这就导致实际执行的WHERE条件被截断或者变形,MySQL查不到匹配的数据,自然只导出表结构了。
可行的解决办法
方法一:用单引号包裹整个WHERE条件
把整个WHERE表达式用单引号括起来,内部字符串用双引号(或者反过来,只要内外引号不冲突就行),这样shell就会把整个条件当作一个完整的参数传递:
mysqldump --user=root --host=localhost DB notes_comments --where='notes_comments.note_id IN (SELECT notes.note_id FROM notes WHERE notes_category_id=1 OR notes.datetime_created > "2018-04-30 18:16:15")' > db.sql
你可以先通过echo验证一下这个条件是否能完整输出:
echo 'notes_comments.note_id IN (SELECT notes.note_id FROM notes WHERE notes_category_id=1 OR notes.datetime_created > "2018-04-30 18:16:15")'
如果输出和你预期的子查询一致,说明shell不会再篡改这个条件了。
方法二:预查询出note_id列表再代入
如果方法一还是有问题,可以先在MySQL里单独执行子查询,把结果拼接成逗号分隔的ID列表:
SELECT GROUP_CONCAT(note_id SEPARATOR ',') FROM notes WHERE notes_category_id=1 OR datetime_created > '2018-04-30 18:16:15';
拿到结果(比如1,2,3,4,5)后,再代入mysqldump的命令,就和你之前能正常运行的格式一致了:
mysqldump --user=root --host=localhost DB notes_comments --where="notes_comments.note_id IN (1,2,3,4,5)" > db.sql
这个方法适合子查询结果集不大的场景,完全避开了shell解析子查询的问题。
方法三:使用临时表中转(可选)
如果子查询逻辑复杂或者结果集很大,可以先把符合条件的note_id存入临时表,再让mysqldump关联临时表查询:
- 先在MySQL中创建临时表并插入数据:
CREATE TEMPORARY TABLE temp_note_ids SELECT note_id FROM notes WHERE notes_category_id=1 OR datetime_created > '2018-04-30 18:16:15';
- 然后用mysqldump关联临时表导出:
mysqldump --user=root --host=localhost DB notes_comments --where="notes_comments.note_id IN (SELECT note_id FROM temp_note_ids)" > db.sql
不过这个方法需要保持MySQL会话打开,临时表才会存在,适合复杂场景。
内容的提问来源于stack exchange,提问作者Sparkeroo
相关产品推荐
相关产品推荐

