如何将ClickHouse查询结果转换为MySQL INSERT语句?
问题
我有一个SQL脚本,可从ClickHouse表中返回约23000行数据,想要将这些数据插入到MySQL的一张表中。由于二者是不同数据库且无可用代理,无法使用INSERT INTO SELECT语法,只能生成包含精确数据的INSERT脚本以便复制粘贴到另一数据库执行。
原查询脚本:
SELECT date, name, sumIf(events>0) ev FROM t1 GROUP BY date, name
返回的数据格式:
2023-10-31 'George' 1261169 2023-11-01 'Alan' 1261370 2023-11-02 'Peter' 1261361
想要修改脚本后返回如下格式的INSERT语句:
INSERT INTO t2 VALUES (2023-10-31, 'George', 1261169), (2023-11-01, 'Alan', 1261370), (2023-11-02, 'Peter', 1261361);
解决方案
可以借助ClickHouse的数组与字符串拼接函数,直接将查询结果格式化为符合MySQL要求的INSERT语句,修改后的SQL如下:
SELECT concat( 'INSERT INTO t2 VALUES ', arrayStringConcat( arrayMap( (d, n, e) -> concat('(', toString(d), ', \'', n, '\', ', toString(e), ')'), groupArray(date), groupArray(name), groupArray(sumIf(events>0)) ), ', ' ), ';' ) FROM t1 GROUP BY date, name INTO OUTFILE '/tmp/mysql_insert.sql' -- 可选:直接输出到文件,避免大量数据在终端显示卡顿或截断
关键逻辑说明
groupArray(column):将分组后的字段值收集为数组,实现批量数据的统一处理arrayMap(...):遍历数组中的每一组数据,拼接成(值1, 值2, 值3)的单行记录格式arrayStringConcat(...):用,连接所有单行记录字符串,形成VALUES子句后的完整数据部分concat(...):将INSERT前缀、拼接好的记录数据、结尾分号组合成完整的可执行SQL语句INTO OUTFILE:针对23000行的大数据量,直接输出到文件比终端显示更高效,也能避免内容截断
注意事项
- 如果MySQL表中
date字段是DATE/DATETIME类型,需要给日期值添加单引号,修改arrayMap内的拼接逻辑为:concat('(\'', toString(d), '\', \'', n, '\', ', toString(e), ')') - 若
name字段包含单引号,需用replace(n, '\'', '\\\'')替换原有的n,避免SQL语法错误 - 生成的INSERT语句长度会比较大,优先使用文件输出的方式获取脚本,再复制到MySQL执行
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

