使用MySQL INTO OUTFILE
时,是否可以以某种方式包含标题?
答案 0 :(得分:140)
您必须自己对这些标题进行硬编码。类似的东西:
SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT ColName1, ColName2, ColName3
FROM YourTable
INTO OUTFILE '/path/outfile'
答案 1 :(得分:74)
Joe Steanelli提供的解决方案可行,但是当涉及数十或数百列时,列表列表不方便。以下是如何在 my_schema 中获取表格 my_table 的列列表。
-- override GROUP_CONCAT limit of 1024 characters to avoid a truncated result
set session group_concat_max_len = 1000000;
select GROUP_CONCAT(CONCAT("'",COLUMN_NAME,"'"))
from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'my_table'
AND TABLE_SCHEMA = 'my_schema'
order BY ORDINAL_POSITION
现在你可以复制&将生成的行粘贴为Joe方法中的第一个语句。
答案 2 :(得分:12)
对于使用ORDER BY的复杂选择,我使用以下内容:
SELECT * FROM (
SELECT 'Column name #1', 'Column name #2', 'Column name ##'
UNION ALL
(
// complex SELECT statement with WHERE, ORDER BY, GROUP BY etc.
)
) resulting_set
INTO OUTFILE '/path/to/file';
答案 3 :(得分:6)
我只是进行2次查询,首先获取带有列名的查询输出(限制1)(没有硬编码,没有连接问题,排序依据,自定义列名等),其次是查询本身,并组合文件到一个CSV文件:
CSVHEAD=`/usr/bin/mysql $CONNECTION_STRING -e "$QUERY limit 1;"|head -n1|xargs|sed -e "s/ /'\;'/g"`
echo "\'$CSVHEAD\'" > $TMP/head.txt
/usr/bin/mysql $CONNECTION_STRING -e "$QUERY into outfile '${TMP}/data.txt' fields terminated by ';' optionally enclosed by '\"' escaped by '' lines terminated by '\r\n';"
cat $TMP/head.txt $TMP/data.txt > $TMP/data.csv
答案 4 :(得分:5)
您可以使用带有lucek答案的预准备语句,并使用CSV中的列名称动态导出表格:
--If your table has too many columns
SET GLOBAL group_concat_max_len = 100000000;
--Prepared statement
SET @SQL = ( select CONCAT('SELECT * INTO OUTFILE \'YOUR_PATH\' FIELDS TERMINATED BY \',\' OPTIONALLY ENCLOSED BY \'"\' ESCAPED BY \'\' LINES TERMINATED BY \'\\n\' FROM (SELECT ', GROUP_CONCAT(CONCAT("'",COLUMN_NAME,"'")),' UNION select * from YOUR_TABLE) as tmp') from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'YOUR_TABLE' AND TABLE_SCHEMA = 'YOUR_SCHEMA' order BY ORDINAL_POSITION );
--Execute it
PREPARE stmt FROM @SQL;
EXECUTE stmt;
感谢lucek。
答案 5 :(得分:5)
这将使您有订购的列和/或限制
SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT * from (SELECT ColName1, ColName2, ColName3
FROM YourTable order by ColName1 limit 3) a
INTO OUTFILE '/path/outfile';
答案 6 :(得分:5)
在NodeJS中的大表上执行mysql查询时,我遇到了类似的问题。我遵循的在CSV文件中包含标头的方法如下
使用OUTFILE查询准备不带标题的文件
SELECT * INTO OUTFILE [FILE_NAME] FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED
BY '\"' LINES TERMINATED BY '\n' FROM [TABLE_NAME]
获取第1点中使用的表的列标题
select GROUP_CONCAT(CONCAT(\"\",COLUMN_NAME,\"\")) as col_names from
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = [TABLE_NAME] AND TABLE_SCHEMA
= [DATABASE_NAME] ORDER BY ORDINAL_POSITION
将列标题附加到使用prepend-file npm软件包在步骤1中创建的文件
使用NodeJS中的promises控制每个步骤的执行。
答案 7 :(得分:3)
如果您熟悉Python或R,这是一种替代作弊,并且您的表可以适合内存。
将SQL表导入Python或R,然后从那里以CSV格式导出,您将获得列名和数据。
以下是我如何使用R,需要RMySQL库:
db <- dbConnect(MySQL(), user='user', password='password', dbname='myschema', host='localhost')
query <- dbSendQuery(db, "select * from mytable")
dataset <- fetch(query, n=-1)
write.csv(dataset, 'mytable_backup.csv')
这有点像作弊但我发现当我的列数太长而无法使用上面的concat方法时,这是一个快速的解决方法。注意:R会添加一个&#39; row.names&#39; CSV开头的列,如果您确实需要依赖CSV来重新创建表格,那么您将要删除它。
答案 8 :(得分:1)
我数据库中的一个例子 表名称传感器和列(id,时间,单位)
select ('id') as id, ('time') as time, ('unit') as unit
UNION ALL
SELECT * INTO OUTFILE 'C:/Users/User/Downloads/data.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM sensor
答案 9 :(得分:1)
所以,如果my_table
中的所有列都是字符数据类型,我们可以将最常见的答案(由Joe,matt和evilguc组合在一起)来自动添加标题在一个“简单”的SQL查询中,例如
select * from (
(select column_name
from information_schema.columns
where table_name = 'my_table'
and table_schema = 'my_schema'
order by ordinal_position)
union all
(select * // potentially complex SELECT statement with WHERE, ORDER BY, GROUP BY etc.
from my_table)) as tbl
into outfile '/path/outfile'
fields terminated by ',' optionally enclosed by '"' escaped by '\\'
lines terminated by '\n';
最后几行输出csv。
请注意,如果my_table
非常大,这可能会很慢。
答案 10 :(得分:1)
由于&#39; include-headers&#39;功能似乎还没有内置,大多数&#34;解决方案&#34;这里需要手动输入列名,和/或不要考虑连接,我建议解决问题。
到目前为止,我发现的最佳选择是使用一个不错的工具(我使用 HeidiSQL )。
提出您的请求,选择网格,只需右键单击并导出到文件。它为干净的出口提供了所有必要的选择,而且应该能满足大多数需求。
同样的想法,user3037511的方法运行良好,可以自动轻松。
只需使用命令行启动您的请求即可获取标题。您可以使用SELECT INTO OUTFILE获取数据...或者通过运行您的查询而不受限制,您可以选择。
请注意,输出重定向到文件在Linux和Windows上都像魅力一样。
这让我想突出显示 80%的时间,当我想使用SELECT FROM INFILE或SELECT INTO OUTFILE时,由于某些限制,我最终使用其他东西(这里没有AWS-RDS上的标题选项&#39;,缺少的权利,等等。)
因此,我没有完全回答操作的问题 ...但它应该回答他的需求 :)
编辑:并实际回答他的问题:不
截至2017-09-07,如果你坚持使用SELECT INTO OUTFILE命令,你就不能包含标题:|
答案 11 :(得分:0)
最简单的方法是自己对列进行硬编码以更好地控制输出文件:
SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT ColName1, ColName2, ColName3
FROM YourTable
INTO OUTFILE '/path/outfile'
答案 12 :(得分:0)
我对这些都不满意,因此在找到解决方案之后,我想将其添加到先前的答案中。 Python == 3.8.6 MySQL == 8.0.19
(请原谅我缺少SO格式化foo。请有人清理。)
请注意几件事:
首先,用于返回列名称的查询无法原谅标点符号。使用'反引号或在'schema_name'和'table_name'周围加上引号会引发“未知列”错误。
WHERE TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table'
第二,列标题名称以单实体元组返回,所有列名称都连接在一个带引号的字符串中。转换为引用列表很简单,但不直观(至少对我而言)。
headers_list = headers_result[0].split(",")
第三,必须对游标进行缓冲,否则“懒惰”的东西将无法根据需要获取结果。对于非常大的表,内存可能是个问题。也许分块可以解决该问题。
cur = db.cursor(buffered=True)
最后,所有类型的UNION尝试都对我产生了错误。通过将整个混乱压缩到字典列表中,使用csv.DictWriter向csv写入变得很简单。
headers_sql = """
SELECT
GROUP_CONCAT(CONCAT(COLUMN_NAME) ORDER BY ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table';
""""
cur = db.cursor(buffered=True)
cur.execute(header_sql)
headers_result = cur.fetchone()
headers_list = headers_result[0].split(",")
rows_sql = """ SELECT * FROM schema.table; """"
data = cur.execute(rows_sql)
data_rows = cur.fetchall()
data_as_list_of_dicts = [dict(zip(headers_list, row)) for row in data_rows]
with open(csv_destination_file, 'w', encoding='utf-8') as destination_file_opened:
dict_writer = csv.DictWriter(destination_file_opened, fieldnames=headers_list)
dict_writer.writeheader() for dict in dict_list:
dict_writer.writerow(dict)
答案 13 :(得分:0)
仅MySQL并不能简单地做到这一点。下面是一个PHP脚本,它将列和数据输出到CSV。
在顶部输入您的数据库名称和表。
<?php
set_time_limit( 24192000 );
ini_set( 'memory_limit', '-1' );
setlocale( LC_CTYPE, 'en_US.UTF-8' );
mb_regex_encoding( 'UTF-8' );
$dbn = 'DB_NAME';
$tbls = array(
'TABLE1',
'TABLE2',
'TABLE3'
);
$db = new PDO( 'mysql:host=localhost;dbname=' . $dbn . ';charset=UTF8', 'root', 'pass' );
foreach( $tbls as $tbl )
{
echo $tbl . "\n";
$path = '/var/lib/mysql/' . $tbl . '.csv';
$colStr = '';
$cols = $db->query( 'SELECT COLUMN_NAME AS `column` FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = "' . $tbl . '" AND TABLE_SCHEMA = "' . $dbn . '"' )->fetchAll( PDO::FETCH_COLUMN );
foreach( $cols as $col )
{
if( $colStr ) $colStr .= ', ';
$colStr .= '"' . $col . '"';
}
$db->query(
'SELECT *
FROM
(
SELECT ' . $colStr . '
UNION ALL
SELECT * FROM ' . $tbl . '
) AS sub
INTO OUTFILE "' . $path . '"
FIELDS TERMINATED BY ","
ENCLOSED BY "\""
LINES TERMINATED BY "\n"'
);
exec( 'gzip ' . $path );
print_r( $db->errorInfo() );
}
?>
您将需要将此目录作为要输出到的目录。 MySQL需要具有写入目录的能力。
$path = '/var/lib/mysql/' . $tbl . '.csv';
您可以在查询中编辑CSV导出选项:
INTO OUTFILE "' . $path . '"
FIELDS TERMINATED BY ","
ENCLOSED BY "\""
LINES TERMINATED BY "\n"'
最后有一个exec调用,用于GZip CSV。
答案 14 :(得分:0)
我想补充一下Sangam Belose提供的答案。这是他的代码:
select ('id') as id, ('time') as time, ('unit') as unit
UNION ALL
SELECT * INTO OUTFILE 'C:/Users/User/Downloads/data.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM sensor
但是,如果您没有在变量中设置"secure_file_priv"
,则可能无法正常工作。为此,请通过以下方法检查在该变量上设置的文件夹:
SHOW VARIABLES LIKE "secure_file_priv"
输出应如下所示:
mysql> show variables like "%secure_file_priv%";
+------------------+------------------------------------------------+
| Variable_name | Value |
+------------------+------------------------------------------------+
| secure_file_priv | C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\ |
+------------------+------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
您可以更改此变量或更改查询以将文件输出到显示的默认路径。
答案 15 :(得分:0)
我用PHP编写代码,使用concat和union函数时遇到了一些麻烦,并且没有使用SQL变量,无论如何我都能使用它,这是我的代码:
//first I connected to the information_scheme DB
$headercon=mysqli_connect("localhost", "USERNAME", "PASSWORD", "information_schema");
//took the healders out in a string (I could not get the concat function to work, so I wrote a loop for it)
$headers = '';
$sql = "SELECT column_name AS columns FROM `COLUMNS` WHERE table_schema = 'YOUR_DB_NAME' AND table_name = 'YOUR_TABLE_NAME'";
$result = $headercon->query($sql);
while($row = $result->fetch_row())
{
$headers = $headers . "'" . $row[0] . "', ";
}
$headers = substr("$headers", 0, -2);
// connect to the DB of interest
$con=mysqli_connect("localhost", "USERNAME", "PASSWORD", "YOUR_DB_NAME");
// export the results to csv
$sql4 = "SELECT $headers UNION SELECT * FROM YOUR_TABLE_NAME WHERE ... INTO OUTFILE '/output.csv' FIELDS TERMINATED BY ','";
$result4 = $con->query($sql4);
答案 16 :(得分:0)
这是一种动态获取列名称标题标题的方法。
/* Change table_name and database_name */
SET @table_name = 'table_name';
SET @table_schema = 'database_name';
SET @default_group_concat_max_len = (SELECT @@group_concat_max_len);
/* Sets Group Concat Max Limit larger for tables with a lot of columns */
SET SESSION group_concat_max_len = 1000000;
SET @col_names = (
SELECT GROUP_CONCAT(QUOTE(`column_name`)) AS columns
FROM information_schema.columns
WHERE table_schema = @table_schema
AND table_name = @table_name);
SET @cols = CONCAT('(SELECT ', @col_names, ')');
SET @query = CONCAT('(SELECT * FROM ', @table_schema, '.', @table_name,
' INTO OUTFILE \'/tmp/your_csv_file.csv\'
FIELDS ENCLOSED BY \'\\\'\' TERMINATED BY \'\t\' ESCAPED BY \'\'
LINES TERMINATED BY \'\n\')');
/* Concatenates column names to query */
SET @sql = CONCAT(@cols, ' UNION ALL ', @query);
/* Resets Group Contact Max Limit back to original value */
SET SESSION group_concat_max_len = @default_group_concat_max_len;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
答案 17 :(得分:0)
实际上即使使用ORDER BY也可以使它工作。
在order by语句中只需要一些技巧 - 我们使用case语句并将header值替换为保证在列表中排序第一的其他值(显然这取决于字段的类型以及是否是排序ASC或DESC)
假设您有三个字段,名称(varchar),is_active(bool),date_something_happens(日期),并且您希望对后两个字段进行排序:
select
'name'
, 'is_active' as is_active
, date_something_happens as 'date_something_happens'
union all
select name, is_active, date_something_happens
from
my_table
order by
(case is_active when 'is_active' then 0 else is_active end) desc
, (case date when 'date' then '9999-12-30' else date end) desc
答案 18 :(得分:0)
我认为如果你使用UNION它会起作用:
select 'header 1', 'header 2', ...
union
select col1, col2, ... from ...
我不知道如何直接使用INTO OUTFILE语法指定标题。
答案 19 :(得分:-2)
SELECT 'ColName1', 'ColName2', 'ColName3' UNION ALL SELECT ColName1, ColName2, ColName3 FROM YourTable INTO OUTFILE 'c:\\datasheet.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n'