SELECT INTO#

SELECT INTO OUTFILE语句将表的查询结果导出为一个文件。

Note

LOAD DATA INFILE 语句与SELECT INTO OUTFILE互补,它用于从指定文件创建表以及加载数据到表中。

Syntax#

SelectIntoStmt
						::= SelectStmt 'INTO' 'OUTFILE' filePath SelectIntoOptionList
						
filePath 
						::= string_literal
SelectIntoOptionList
						::= 'OPTIONS' '(' SelectInfoOptionItem (',' SelectInfoOptionItem)* ')'

SelectInfoOptionItem
						::= 'DELIMITER' '=' string_literal
						|'HEADER' '=' bool_literal
						|'NULL_VALUE' '=' string_literal
						|'FORMAT' '=' string_literal
						|'MODE' '=' string_literal

SELECT INTO OUTFILE分为三个部分。

  • 第一部分是一个普通的SELECT语句,通过这个SELECT语句来查询所需要的数据;

  • 第二部分是filePath,定义将查询的记录导出到哪个文件中,详情见FilePath

  • 第三部分是SelectIntoOptionList为可选选项,其可能的取值有:

配置项

类型

默认值

描述

delimiter

String

,

列分隔符,默认为‘,

header

Boolean

true

是否包含表头, 默认为true

null_value

String

null

NULL填充值,默认填充"null"

format

String

csv

输出文件格式:
csv:不显示指明format时,默认为该值
parquet:集群版离线模式支持导出parquet格式文件,但集群在线和单机版不支持

mode

String

error_if_exists

输出模式:
error_if_exists: 表示若文件已经在则报错。
overwrite: 表示若文件已存在,数据将覆盖原文件内容。
append:表示若文件已存在,数据将追加到原文件后面。
不显示配置时,默认为error_if_exists

quote

String

“”

输出数据的包围字符串,字符串长度<=1。默认为””,表示输出数据包围字符串为空。当配置包围字符串时,将使用包围字符串包围一个field。例如,我们配置包围字符串为"#",原始数据为{1, 1.0, This is a string, with comma}。输出的文本为1, 1.0, #This is a string, with comma#。

Important

请注意,目前仅有集群版支持quote字符的转义。所以,如果您使用的是单机版,请谨慎选择quote字符,保证原始字符串内并不包含quote字符。

FilePath#

FilePath支持’file://’, ‘hdfs://’, ‘hive://’三种。

导出到Hive#

路径格式:‘hive://[db.]table’。不指定db则导入到Hive的’default_db’。表可以不存在,但如果指定db,db必须存在。

  • Hive需要Spark支持与连接到Hive的配置,请参考Hive 支持

  • 不支持导出到Hive不存在的数据库。如果指定的Hive数据库不存在,OpenMLDB不会为此在Hive中创建该数据库。(OpenMLDB创建Hive数据库,会导致该数据库的表存储路径变化。)

SQL语句模版#

SELECT ... INTO OUTFILE 'file_path' OPTIONS (key = value, ...)

Examples#

  • 从表t1查询输出到data.csv文件中,使用,作为列分隔符

SELECT col1, col2, col3 FROM t1 INTO OUTFILE 'data.csv' OPTIONS ( delimiter = ',' );
  • 从表t1查询输出到data.csv文件中,使用作为列分隔符,NULL值的填充值为NA字符串:

SELECT col1, col2, col3 FROM t1 INTO OUTFILE 'data2.csv' OPTIONS ( delimiter = '|', null_value='NA');

Q&A#

Q: select into 错误 Found duplicate column(s)?

Exception in thread "main" org.apache.spark.sql.AnalysisException: Found duplicate column(s) when inserting into file:/tmp/out: `c1`;
     at org.apache.spark.sql.util.SchemaUtils$.checkColumnNameDuplication(SchemaUtils.scala:90)
     at org.apache.spark.sql.execution.datasources.InsertIntoHadoopFsRelationCommand.run(InsertIntoHadoopFsRelationCommand.scala:84)
     at org.apache.spark.sql.execution.command.DataWritingCommandExec.sideEffectResult$lzycompute(commands.scala:108)
     at org.apache.spark.sql.execution.command.DataWritingCommandExec.sideEffectResult(commands.scala:106)
     at org.apache.spark.sql.execution.command.DataWritingCommandExec.doExecute(commands.scala:131)
     at org.apache.spark.sql.execution.SparkPlan.$anonfun$execute$1(SparkPlan.scala:175)
     at org.apache.spark.sql.execution.SparkPlan.$anonfun$executeQuery$1(SparkPlan.scala:213)
     at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151)
     at org.apache.spark.sql.execution.SparkPlan.executeQuery(SparkPlan.scala:210)
     at org.apache.spark.sql.execution.SparkPlan.execute(SparkPlan.scala:171)
     at org.apache.spark.sql.execution.QueryExecution.toRdd$lzycompute(QueryExecution.scala:122)
     at org.apache.spark.sql.execution.QueryExecution.toRdd(QueryExecution.scala:121)
     at org.apache.spark.sql.DataFrameWriter.$anonfun$runCommand$1(DataFrameWriter.scala:944)

A: 查询语句是允许列名重复的。但SELECT INTO除了查询还需要写入,写入中会检查重复列名。请避免重复列名,可以用c1 as c_new来重命名列。