当前位置:  开发笔记 > 编程语言 > 正文

如何以CSV格式输出MySQL查询结果?

如何解决《如何以CSV格式输出MySQL查询结果?》经验,为你挑选了21个好方法。

有没有一种简单的方法可以从Linux命令行运行MySQL查询并以CSV格式输出结果?

这就是我现在正在做的事情:

mysql -u uid -ppwd -D dbname << EOQ | sed -e 's/        /,/g' | tee list.csv
select id, concat("\"",name,"\"") as name
from students
EOQ

当有很多列需​​要用引号括起来,或者结果中有引号需要转义时,它会变得混乱.



1> Paul Tomblin..:

来自http://www.tech-recipes.com/rx/1475/save-mysql-query-results-into-a-text-or-csv-file/

SELECT order_id,product_name,qty
FROM orders
WHERE foo = 'bar'
INTO OUTFILE '/var/lib/mysql-files/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

使用此命令将不会导出列名称.

另请注意,/var/lib/mysql-files/orders.csv将在运行MySQL 的服务器上.运行MySQL进程的用户必须具有写入所选目录的权限,否则命令将失败.

如果要从远程服务器(尤其是托管或虚拟机,如Heroku或Amazon RDS)将输出写入本地计算机,则此解决方案不适用.


@BogdanGusiev,您可以通过在真实查询之前添加"SELECT'order_id','product_name','qty'UNION"来包含标题.首先选择查询返回头,第二个查询返回实数据; UNION将它加入到一起.
问题指定MySQL,而不是"符合标准".
如何包含标题?
@Michael Butler:嗯,不,实际上.如果您使用的是Amazon RDS,Heroku或任何其他托管解决方案,则您不太可能只能写入其他人的服务器.
@Tomas如果你有权访问远程文件系统和MySQL,你必须能够在某处写.而不是/ tmp,请尝试/home/yourusername/file.csv - 如果失败,并且结果集不是那么大,您可以从SSH客户端复制输出并粘贴到本地计算机.
如果mysql运行`--secure-file-priv`,你可能无法写入`/ tmp`.运行`SHOW VARIABLES LIKE"secure_file_priv";`查看您可以写入的目录.
此解决方案仅在您可以访问MYSQL服务器文件系统时起作用,即您具有对该服务器的直接管理访问权限(并且不介意使用数据导出来填充其驱动器).当用户无权访问服务器时,这不是解决方案,例如,用户不是管理员,或者用户是管理员,但数据库正在远程运行,例如在AWS.
@TMS,您仍需要"授权文件"权限,另请参阅http://stackoverflow.com/questions/6091427/mysql-into-outfile-access-denied-but-my-user-has-all-access -and-的倍
在允许此方法所需的File_priv权限工作之前,数据库管理员应仔细考虑.见http://docs.oracle.com/cd/E17952_01/refman-5.0-en/security-against-attack.html
如果你有很多列,并且你需要他们所有:`SELECT列名information_schema.columns在表格="订单" INTO OUTFILE"/tmp/orders_columns.csv"结尾田野'ENCLOSED BY""" LINES TERMINATED BY' ,';`
如果您的记录中有换行符或双引号,我认为这种方法效果不好......似乎没有一种方法可以在输出中替换"with""(我认为是CSV中的自定义)也逃避换行.
在Windows机器上,`OUTFILE`字符串应该从反斜杠中转义.例如,我使用字符串''C:\\ wamp \\ bin \\ mysql \\ mysql5.5.24 \\ bin \\ output \\ orders.csv'`

2> Stan..:
$ mysql your_database --password=foo < my_requests.sql > out.csv

哪个是制表符分隔.像这样管道以获得真正的CSV(感谢@therefromhere):

... .sql | sed 's/\t/,/g' > out.csv


sed'fix'不会补偿可能出现在任何所选数据中的逗号,并会相应地输出您的列
它是以制表符分隔的,而不是逗号分隔的.
消极性是有效的..它现在可能适合你,但是当你的数据包含标签或逗号等时,它可能会在将来咬你.
@Flimm,假设你没有在字段中嵌入逗号/制表符,你可以通过将结果传递给`|来转换它 sed's /\t /,/ g'`
不仅如此,它还允许从远程数据库主机创建内容,这与写入本地文件系统的其他内容不同.
Mac OSX无法识别`\ t`。您可以使用`ctrl` +`v`然后插入`tab`来插入制表符文字。
对于某些数据来说这是可以的,但是如果你有任意文本字段或二进制数据那就错了.例如,您的字段可能包括制表符,回车符,反斜杠或引号.

3> serbaut..:

mysql --batch,-B

使用制表符作为列分隔符打印结果,每行都在新行上.使用此选项,mysql不使用历史记录文件.批处理模式导致非表格输出格式和特殊字符的转义.可以使用原始模式禁用转义; 请参阅--raw选项的说明.

这将为您提供一个制表符分隔文件.由于逗号(或包含逗号的字符串)未进行转义,因此将分隔符更改为逗号并不简单.


这是一个首选解决方案:1)在UNIX中常见的制表符分隔值列表2)大多数导入系统本身都支持TSV导入,包括Excel,OpenOffice Spreadsheets等.3)无需转义文本字段的引号字符4 )使命令行导出变得轻而易举
一个巧妙的技巧:如果您将制表符分隔文件保存为.xls而不是.csv,它将在excel中打开,无需"文本到数据"转换,也不会出现任何区域设置问题.
这是最好的解决方案,因为与第一个不同的是,不需要在RDS等服务器上拥有权限
@Joey T-您仍然需要转义制表符和回车符。同样,如果字段的内容看起来像是带引号或转义的字段,则导入的内容可能看起来不像原始内容。
您会遇到NULL问题..它们将以字符串null形式出现。

4> Tim Harding..:

这是一种相当粗糙的方式.发现它在某个地方,不能拿任何功劳

mysql --user=wibble --password wobble -B -e "select * from vehicle_categories;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > vehicle_categories.csv

效果很好.再一次,虽然正则表达式证明只写.


正则表达式说明:

s ///表示替换第一个//与第二个//之间的内容//

最后的"g"是一个修饰符,意思是"所有实例,而不仅仅是第一个"

^(在此上下文中)表示行的开头

$(在此上下文中)表示行尾

所以,把它们放在一起:

s/'/\'/          replace ' with \'
s/\t/\",\"/g     replace all \t (tab) with ","
s/^/\"/          at the beginning of the line place a "
s/$/\"/          at the end of the line place a "
s/\n//g          replace all \n (newline) with nothing


乍一看,这看起来很破碎.内容中的标签和回车将被错误处理."S/'/ \'/;" 什么都不做,因为shell命令中的双引号使用反斜杠.许多其他类似的错误与反斜杠丢失.在db字段中不处理反斜杠.
如果你有一个包含制表符,反斜杠,"","和许多其他东西的文本字段,这将会中断.正则表达式不是解决这个问题的方法
-e标志正是我要的!谢谢!

5> strickli..:

仅限Unix/Cygwin,通过'tr'管道:

mysql  -e "" | tr '\t' ',' > data.csv

注意:它既不处理嵌入式逗号,也不处理嵌入式选项卡.


也没有嵌入反斜杠或回车

6> hrvoj3e..:

这节省了我几次.快,它的工作原理!

- 批量

- 生的

例:

mysql -udemo_user -p -h127.0.0.1 --port=3306 \
   --default-character-set=utf8mb4 --database=demo_database \
   --batch --raw < /tmp/demo_sql_query.sql > /tmp/demo_csv_export.tsv


除非我遗漏了什么,否则会创建一个TSV文件,而不是CSV文件......

7> 小智..:

Paul Tomblin给出的OUTFILE解决方案会导致在MySQL服务器本身上写入文件,因此只有在您具有FILE访问权限以及登录访问权限或其他从该框中检索文件的方法时才能使用该文件.

如果您没有这样的访问权限,并且制表符分隔的输出是CSV的合理替代(例如,如果您的最终目标是导入到Excel),那么Serbaut的解决方案(使用mysql --batch和可选--raw)是可行的方法.



8> David Oliver..:

MySQL Workbench可以将记录集导出为CSV,它似乎可以很好地处理字段中的逗号.CSV在OpenOffice中打开很好.


万万大卫感谢 花了3个小时让新行正确输出数据中的HTML内容后,我使用了MySQL Workbench,并在2分钟内准备好了我的CSV文件.

9> 小智..:

怎么样:

mysql your_database -p < my_requests.sql | awk '{print $1","$2}' > out.csv


对于带空格的字段值,这会失败.
我真的很喜欢这一个.它更干净,我喜欢使用awk.但是,我可能会这样做:`mysql -uUser -pPassword your_database out.csv`

10> mc0e..:

迄今为止,除Mysql工作台之外的所有解决方案都是错误的,并且对于MySQL DB中的至少一些可能的内容来说可能是不安全的(即安全问题).

Mysql Workbench(以及类似的PHPMyAdmin)提供了一个正式正确的解决方案,但设计用于将输出下载到用户的位置.它们对于自动化数据导出等问题并不那么有用.

无法从输出中生成可靠的正确csv,mysql -B -e 'SELECT ...'因为它无法对字段中的回车符和空格进行编码.MySQL的'-s'标志确实会执行反斜杠转义,并可能导致正确的解决方案.但是,使用脚本语言(一个具有良好的内部数据结构,而不是bash),以及编码问题已经仔细制定的库,更加安全.

我想为此写一个脚本,但是当我想到我称之为什么时,我就想到了用同一个名字搜索已有的作品.虽然我没有彻底解决它,但解决方案看起来很有希望.根据您的应用程序,指定SQL命令的yaml方法可能会或可能不会吸引人.我对于更新版本的ruby的要求并不像我的Ubuntu 12.04笔记本电脑或Debian Squeeze服务器那样标准.是的我知道我可以使用RVM,但我不想为了这么简单的目的而维护它.

希望有人会指出一个合适的工具,这需要进行一些测试.否则,当我找到或写一个时,我可能会更新它.



11> Sri Murthy U..:

从命令行,您可以执行以下操作:

mysql -h *hostname* -P *port number* --database=*database_name* -u *username* -p -e *your SQL query* | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > *output_file_name.csv*

致谢:将 Amazon RDS中的表格导出为csv文件



12> Chris Johnso..:

此页面上的许多答案都很薄弱,因为它们无法处理CSV格式的一般情况.例如,嵌入在字段中的逗号和引号以及最终总是出现的其他条件.我们需要一个适用于所有有效CSV输入数据的通用解决方案.

这是Python中一个简单而强大的解决方案:

#!/usr/bin/env python

import csv
import sys

tab_in = csv.reader(sys.stdin, dialect=csv.excel_tab)
comma_out = csv.writer(sys.stdout, dialect=csv.excel)

for row in tab_in:
    comma_out.writerow(row)

命名该文件tab2csv,将其放在路径上,赋予它执行权限,然后使用它列出:

mysql OTHER_OPTIONS --batch --execute='select * from whatever;' | tab2csv > outfile.csv

Python CSV处理功能涵盖了CSV输入格式的极端情况.

这可以通过流方法来改进以处理非常大的文件.


更可靠的解决方案是使用Python实际连接到数据库,然后您应该更轻松地完成处理更大数据集(分块结果,流式传输等)所需的操作.

13> zloctb..:

    逻辑:

CREATE TABLE () (SELECT data FROM other_table ) ENGINE=CSV ;

创建CSV表时,服务器会在数据库目录中创建表格式文件.该文件以表名开头,扩展名为.frm.存储引擎还会创建一个数据文件.它的名称以表名开头,并具有.CSV扩展名.数据文件是纯文本文件.将数据存储到表中时,存储引擎会以逗号分隔值格式将其保存到数据文件中.



14> Ben..:

这个答案使用Python和流行的第三方库PyMySQL.我正在添加它,因为Python的csv库足够强大,可以正确处理许多不同的风格,.csv没有其他答案使用Python代码与数据库交互.

import contextlib
import csv
import datetime
import os

# https://github.com/PyMySQL/PyMySQL
import pymysql

SQL_QUERY = """
SELECT * FROM my_table WHERE my_attribute = 'my_attribute';
"""

# embedding passwords in code gets nasty when you use version control
# the environment is not much better, but this is an example
# /sf/ask/17360801/
SQL_USER = os.environ['SQL_USER']
SQL_PASS = os.environ['SQL_PASS']

connection = pymysql.connect(host='localhost',
                             user=SQL_USER,
                             password=SQL_PASS,
                             db='dbname')

with contextlib.closing(connection):
    with connection.cursor() as cursor:
        cursor.execute(SQL_QUERY)
        # Hope you have enough memory :)
        results = cursor.fetchall()

output_file = 'my_query-{}.csv'.format(datetime.datetime.today().strftime('%Y-%m-%d'))
with open(output_file, 'w', newline='') as csvfile:
    # http://stackoverflow.com/a/17725590/2958070 about lineterminator
    csv_writer = csv.writer(csvfile, lineterminator='\n')
    csv_writer.writerows(results)


@AlexanderBaltasar,对,它看起来很有用,但它没有使用Python代码与数据库进行交互.请参阅有关该问题的评论.

15> Jonathan..:

除上述答案外,您还可以拥有一个使用CSV引擎的MySQL表.

然后,您的硬盘上将有一个文件,该文件将始终采用CSV格式,您可以在不进行处理的情况下进行复制.



16> 小智..:

这很简单,它适用于任何不需要批处理模式或输出文件的东西:

select concat_ws(',',
    concat('"', replace(field1, '"', '""'), '"'),
    concat('"', replace(field2, '"', '""'), '"'),
    concat('"', replace(field3, '"', '""'), '"'))

from your_table where etc;

说明:

    在每个字段中替换"with"" - > replace(field1,'"','""')

    用引号括起每个结果 - > concat('"',result1,'"')

    在每个引用的结果之间放置一个逗号 - > concat_ws(',',quoted1,quoted2,...)

而已!



17> johntellsall..:

要扩展以前的答案,以下单行将单个表导出为制表符分隔文件.它适用于自动化,每天导出数据库.

mysql -B -D mydatabase -e 'select * from mytable'

方便的是,我们可以使用相同的技术列出MySQL的表,并描述单个表上的字段:

mysql -B -D mydatabase -e 'show tables'

mysql -B -D mydatabase -e 'desc users'

Field   Type    Null    Key Default Extra
id  int(11) NO  PRI NULL    auto_increment
email   varchar(128)    NO  UNI NULL    
lastName    varchar(100)    YES     NULL    
title   varchar(128)    YES UNI NULL    
userName    varchar(128)    YES UNI NULL    
firstName   varchar(100)    YES     NULL    


使用`sed -e'/\t /,/ g'`只有在您确定数据不包含任何逗号或制表符时才是安全的.
要转换为CSV:`mysql -B -D mydatabase -e'select*from mytable'| sed -e's /\t /,/ g'`

18> Brian..:

此外,如果您在Bash命令行上执行查询,我相信该tr命令可用于将默认选项卡替换为任意分隔符.

$ echo "SELECT * FROM Table123" | mysql Database456 | tr "\t" ,



19> Michael Cole..:

在user7610的基础上,这是最好的方法.随着mysql outfile有文件的所有权和覆盖问题的60分钟.

它并不酷,但它可以在5分钟内完成.

php csvdump.php localhost root password database tablename > whatever-you-like.csv

name;
}
fputcsv($output, $fields);

// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);

?>



20> 小智..:

这是我做的:

echo $QUERY | \
  mysql -B  $MYSQL_OPTS | \
  perl -F"\t" -lane 'print join ",", map {s/"/""/g; /^[\d.]+$/ ? $_ : qq("$_")} @F ' | \
  mail -s 'report' person@address

perl脚本(从其他地方狙击)在将制表符间隔字段转换为CSV方面做得很好.



21> Denilson Sá ..:

不完全是CSV格式,但MySQL 客户端的tee命令可用于将输出保存到本地文件中:

tee foobar.txt
SELECT foo FROM bar;

你可以使用它来禁用它notee.

问题SELECT … INTO OUTFILE …;是它需要在服务器上写文件的权限.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有