MySQL 쿼리 결과를 CSV 형식으로 출력하는 방법은 무엇입니까?


1183

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
REPLACE()쿼리에서 인용 부호를 피하기 위해 사용할 수 있습니다 .
dsm

[this stackoverflow] [1] [1]에서 내 대답을보십시오 : stackoverflow.com/questions/12242772/…
biniam


2
이 stackoverflow 질문에 대한 대답은 아마도 가장 좋은 방법 일 것입니다. stackoverflow.com/questions/3760631/mysql-delimiter-question
Samuel Åslund

MariaDB 버그 추적기 ( jira.mariadb.org/browse/MDEV-12879 ) 에 대한 기능 요청을 작성 했습니다. 투표 할 수 있습니다.
Jared Beck

답변:


1760

에서 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';

이 명령을 사용하면 열 이름을 내보낼 수 없습니다.

또한 MySQL을 실행 /var/lib/mysql-files/orders.csv하는 서버 에있을 것입니다 . MySQL 프로세스가 실행중인 사용자는 선택한 디렉토리에 쓸 수있는 권한이 있어야합니다. 그렇지 않으면 명령이 실패합니다.

원격 서버 (특히 Heroku 또는 Amazon RDS와 같은 호스팅 또는 가상화 시스템)에서 로컬 시스템에 출력을 쓰려면이 솔루션이 적합하지 않습니다.


16
@Tomas 원격 파일 시스템과 MySQL에 액세스 할 수 있으면 어딘가에 쓸 수 있어야합니다. / tmp 대신 /home/yourusername/file.csv를 시도하십시오. 실패하고 결과 세트가 크지 않은 경우 SSH 클라이언트의 출력을 복사하여 로컬 시스템에 붙여 넣을 수 있습니다.
마이클 버틀러

63
이 질문은 "표준 준수"가 아닌 MySQL을 지정했습니다.
Paul Tomblin

35
헤더를 포함시키는 방법?
Bogdan Gusiev

66
@BogdanGusiev의 경우 실제 쿼리 앞에 "SELECT 'order_id', 'product_name', 'qty'UNION"을 추가하여 헤더를 포함 할 수 있습니다. 첫 번째 쿼리 선택은 헤더를 반환하고 두 번째 쿼리는 실제 데이터를 반환합니다. UNION이 함께 합류했습니다.
petrkotek

19
@ 마이클 버틀러 : 글쎄요. Amazon RDS, Heroku 또는 기타 호스팅 된 솔루션을 사용하는 경우 다른 사람의 서버에 쓸 수 없을 것입니다.
Ken Kinder

459
$ mysql your_database --password=foo < my_requests.sql > out.csv

탭으로 구분됩니다. 그런 식으로 파이프하여 진정한 CSV를 얻으십시오 (@therefromhere 덕분에).

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

5
로컬 파일 시스템에 쓰는 것과는 달리 원격 데이터베이스 호스트에서 컨텐츠를 작성할 수 있습니다.
tmarthal

31
쉼표로 구분되지 않고 탭으로 구분됩니다.
Flimm

13
@Flimm, 필드에 쉼표 / ​​탭이 포함되어 있지 않다고 가정하면 결과를 파이프로 변환하여 변환 할 수 있습니다.| sed 's/\t/,/g'
John Carter

111
sed 'fix'는 선택된 데이터에 나타날 수있는 쉼표를 보상하지 않으며 그에 따라 출력 된 열을 기울입니다
Joey T

14
부정은 유효합니다. 그것은 지금 당신을 위해 작동 할 수 있지만 데이터가 탭이나 쉼표 등을 포함 할 때 미래에 당신을 물 수 있습니다.
John Hunt

204

mysql-배치, -B

탭을 열 구분자로 사용하고 각 행을 새 줄에 사용하여 결과를 인쇄하십시오. 이 옵션을 사용하면 mysql은 기록 파일을 사용하지 않습니다. 배치 모드는 비표 형식의 출력 형식과 특수 문자를 이스케이프 처리합니다. 원시 모드를 사용하여 이스케이프를 비활성화 할 수 있습니다. --raw 옵션에 대한 설명을 참조하십시오.

이렇게하면 탭으로 구분 된 파일이 제공됩니다. 쉼표 (또는 쉼표를 포함하는 문자열)가 이스케이프되지 않으므로 구분 기호를 쉼표로 변경하는 것은 간단하지 않습니다.


12
1) 탭으로 구분 된 값 목록은 UNIX에서 일반적입니다. 2) TSV 가져 오기는 Excel, OpenOffice Spreadsheets 등 대부분의 가져 오기 시스템에서 기본적으로 지원됩니다. 3) 텍스트 필드에 따옴표를 이스케이프 할 필요가 없습니다. 4 )는 명령 행 수출을 산들 바람으로 만듭니다
Joey T

5
이것은 RDS와 같은 서버에 대한 권한이 필요하지 않기 때문에 가장 좋은 솔루션입니다
Muayyad Alsadi

8
깔끔한 트릭 : 탭으로 구분 된 파일을 .csv 대신 .xls로 저장하면 "텍스트에서 데이터로"변환 할 필요없이 지역 설정 문제없이 Excel에서 열 수 있습니다.
serbaut

3
@Joey T-여전히 탭과 캐리지 리턴을 이스케이프해야합니다. 또한 필드의 내용이 따옴표로 묶거나 이스케이프 된 필드처럼 보이는 경우 가져온 내용이 원본과 다르게 보일 수 있습니다.
mc0e

2
NULL에 문제가있을 것입니다. 문자열 null로 나옵니다.
Jonathan

141

여기에 상당히 나쁜 방법이 있습니다. 어딘가에 그것을 발견, 신용을 취할 수 없습니다

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

3
-e 플래그는 내가 찾던 것입니다! 감사!
Gaurav Gupta

1
이 정규 표현식은 실제로 매우 간단합니다. 이 페이지의 다른 많은 답변과 마찬가지로의 출력을 정리합니다 mysql -B. 정규식을 별도의 줄에 개별 문으로 분리하면 (정규식을 아는 사람에게는) 이해하기가 매우 간단합니다.
Mei

7
언뜻보기에, 이것은 꽤 부서진 것처럼 보입니다. 내용의 탭 및 캐리지 리턴이 잘못 처리됩니다. "에스/'/\'/;" 쉘 명령의 큰 따옴표는 백 슬래시를 사용하기 때문에 아무것도 수행하지 않습니다. 백 슬래시가 손실되는 다른 많은 유사한 버그. db 필드에서 백 슬래시를 처리하지 않습니다.
mc0e

1
이 명령은 Linux에서는 잘 작동하지만 Mac에서는 작동하지 않는 것 같습니다.
Hemerson Varela

6
탭, 백 슬래시 ","및 기타 여러 가지 가 포함 된 텍스트 필드가있는 경우이 오류가 발생합니다 . 정규식은 하지 이 문제를 해결하는 방법
에이단

93

Unix / Cygwin 전용, 'tr'을 통해 파이프하십시오.

mysql <database> -e "<query here>" | tr '\t' ',' > data.csv

주의 : 이것은 내장 된 쉼표 나 내장 된 탭을 처리하지 않습니다.


53

이로 인해 몇 시간이 절약되었습니다. 빠르고 작동합니다!

--batch 을 열 구분자로 사용하고 각 행을 새 줄에 사용하여 결과를 인쇄합니다 .

--raw는 문자 이스케이프를 비활성화합니다 (\ n, \ t, \ 0 및 \)

예:

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

완전성을 위해 csv로 변환 할 수 있습니다 (그러나 탭은 필드 값 안에있을 수 있으므로 주의하십시오 -예를 들어 텍스트 필드)

tr '\t' ',' < file.tsv > file.csv


4
내가 빠진 것이 아니라면 이것은 CSV 파일이 아닌 TSV 파일을 생성합니다.
PressingOnAlways

@PressingOnAlways 예. MySQL doc quote : "탭을 열 구분자로 사용하고 각 행을 새 줄에 인쇄하여 결과를 인쇄하십시오." 그러나 구문 분석은 구분 기호에 문제가되어서는 안됩니다. 내 고객을 위해 Excel 파일을 만드는 데 사용했습니다.
hrvoj3e

39

Paul Tomblin이 제공 한 OUTFILE 솔루션으로 인해 파일이 MySQL 서버 자체에 작성되므로 FILE 이있는 경우에만 작동합니다. 로그인 액세스 또는 해당 상자에서 파일을 검색 할 수있는 다른 방법뿐만 아니라 액세스 권한 .

이러한 액세스 권한이없고 탭으로 구분 된 출력이 CSV를 대체 할 수있는 합리적인 대안이라면 (예 : 최종 목표가 Excel로 가져 오는 경우) Serbaut의 솔루션 ( mysql --batch및 선택적으로 사용 --raw)이 사용 됩니다.


36

MySQL Workbench 는 레코드 세트를 CSV로 내보낼 수 있으며 필드에서 쉼표를 잘 처리하는 것 같습니다. CSV는 OpenOffice fine에서 열립니다.


2
백만 데이비드에게 감사합니다. 데이터에 HTML 내용을 올바로 출력하기 위해 줄 바꿈을 얻는 데 3 시간을 보낸 후 MySQL Workbench를 사용했으며 2 분 안에 CSV 파일을 준비했습니다.
mr-euro

방금 XML로도 저장할 수 있다는 것을 알았습니다. XSLT를 사용하여이 XML을 대상 응용 프로그램으로 가져 오기에 적합한 CSV 파일로 변환하여 한 응용 프로그램에서 다른 응용 프로그램으로 마이그레이션하려고합니다.
David Oliver

mysql Workbench는 가져 오기 내보내기 기능에 가장 적합한 옵션입니다.
cijagani

1
mysql workbench를 사용하여 50 만 개가 넘는 행을 성공적으로 내보냈으므로 큰 파일은 문제가되지 않습니다. 쿼리를 실행하기 전에 선택 제한을 제거해야하며 my.ini 파일에서 다음 값을 늘려야 할 수도 있습니다. max_allowed_packet = 500M, net_read_timeout = 600, net_write_timeout = 600
Vincent

3
CSV로 데이터를 내보낼 때 MySQL Workbench에 메모리 누수가 발생하는 경우가 있습니다 .1 또는 2 백만 행과 같은 큰 데이터 세트가있는 경우 12GB의 RAM (내 리눅스 머신에서 테스트 됨)이 충분하지 않고 메모리가 지워지지 않으면 메모리가 지워지지 않습니다 죽이거나 중지하십시오. 큰 데이터 세트의 경우 솔루션이 아닙니다.
Ostico

33

어때요?

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

2
나는 이것을 정말로 좋아합니다. 훨씬 깨끗하고 awk를 사용하는 것이 좋습니다. 그러나 나는 아마도 이것과 함께 갔을 것입니다 : mysql -uUser -pPassword your_database < my_requests.sql | awk 'BEGIN{OFS="=";} {print $1,$2}' > out.csv
Josh

7
공백이있는 필드 값에 대해서는 실패합니다.
Barun Sharma

29

MySQL 워크 벤치 솔루션을 제외한 현재까지의 모든 솔루션은 mysql db의 가능한 일부 컨텐츠에 대해 올바르지 않으며 안전하지 않을 수 있습니다 (예 : 보안 문제).

MYSQL Workbench (및 유사하게 PHPMyAdmin)는 공식적으로 올바른 솔루션을 제공하지만 출력을 사용자의 위치로 다운로드하도록 설계되었습니다. 데이터 내보내기 자동화와 같은 작업에는 그다지 유용하지 않습니다.

출력에서 안정적으로 올바른 CSV를 생성 할 수 없습니다. mysql -B -e 'SELECT ...'필드에서 캐리지 리턴과 공백을 인코딩 할 수 없으므로 할 수 없습니다. mysql에 대한 '-s'플래그는 백 슬래시 이스케이프를 수행하며 올바른 솔루션으로 이어질 수 있습니다. 그러나 스크립팅 언어 (bash가 아닌 적절한 내부 데이터 구조를 가진 언어)와 인코딩 문제가 이미 신중하게 해결 된 라이브러리를 사용하는 것이 훨씬 안전합니다.

나는 이것을 위해 스크립트를 작성하는 것에 대해 생각했지만, 내가 부르는 것에 대해 생각하자마자 같은 이름으로 기존 작품을 검색하는 것이 나에게 일어났다. 철저히 다루지 않았지만 https://github.com/robmiller/mysql2csv 의 솔루션 은 유망합니다. 응용 프로그램에 따라 SQL 명령을 지정하기위한 yaml 방식이 유용 할 수도 있고 그렇지 않을 수도 있습니다. 또한 Ubuntu 12.04 랩톱 또는 Debian Squeeze 서버에서 표준으로 제공되는 것보다 최신 버전의 루비에 대한 요구 사항에 감격하지 않았습니다. 예, RVM을 사용할 수 있다는 것을 알고 있지만 그러한 간단한 목적으로 유지 관리하지는 않겠습니다.

누군가가 적절한 도구를 지적하기를 바랍니다. 약간의 테스트가 필요합니다. 그렇지 않으면 이것을 찾거나 쓸 때 이것을 업데이트 할 것입니다.


1
테이블의 복잡한 문자열에 대해서는 bash뿐만 아니라 적절한 라이브러리를 사용해야합니다. nodejs가 이러한 종류의 작업에 더 나은 솔루션을 가지고 있다고 생각합니다. 이
yeya

1
안녕하세요, 좋은 대답은 stackoverflow.com/a/35123787/1504300 아래에 제안 된 파이썬 솔루션에 대한 링크를 추가하는 것 입니다. 게시물을 수정하려고했지만 수정이 거부되었습니다
정말로 멋진

26

이 페이지의 많은 답변은 CSV 형식으로 발생할 수있는 일반적인 경우를 처리하지 않기 때문에 약합니다. 예를 들어 필드와 다른 조건에 항상 포함되는 쉼표와 따옴표. 유효한 모든 CSV 입력 데이터에 적합한 일반적인 솔루션이 필요합니다.

다음은 파이썬에서 간단하고 강력한 솔루션입니다.

#!/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 입력 형식의 경우를 다룹니다.

스트리밍 방식을 통해 매우 큰 파일을 처리하도록 개선 할 수 있습니다.


8
훨씬 더 신뢰할 수있는 솔루션은 실제로 Python으로 데이터베이스에 연결하는 것이므로 더 큰 데이터 세트 (청킹 결과, 스트리밍 등)를 처리하기 위해 수행해야 할 작업을보다 쉽게 ​​수행 할 수 있습니다.
Josh Rumbut

@JoshRumbut, 정말 늦었지만 귀하의 의견을 보완하기 위해 stackoverflow.com/a/41840534/2958070 을 만들었습니다
Ben


17
  1. 논리 :

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

CSV 테이블을 작성하면 서버는 데이터베이스 디렉토리에 테이블 형식 파일을 작성합니다. 파일 이름은 테이블 이름으로 시작하고 확장자는 .frm입니다. 스토리지 엔진은 데이터 파일도 생성합니다. 이름은 테이블 이름으로 시작하며 확장자는 .CSV입니다. 데이터 파일은 일반 텍스트 파일입니다. 데이터를 테이블에 저장하면 스토리지 엔진이 데이터를 쉼표로 구분 된 값 형식으로 데이터 파일에 저장합니다.


1
다른 조정이 필요하지 않은 것이 맞기 때문에 좋습니다.
Andrew Schulman

13

이 답변은 Python 및 널리 사용되는 타사 라이브러리 PyMySQL을 사용 합니다. 파이썬의 csv 라이브러리는 많은 다른 풍미 를 올바르게 처리 할만 큼 강력 .csv하고 다른 답변이 파이썬 코드를 사용하여 데이터베이스와 상호 작용하지 않기 때문에 추가 하고 있습니다.

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
# /programming/12461484
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)

파이썬을 사용한 답변이 이미 제공되었습니다. stackoverflow.com/a/35123787/5470883
Alexander Baltasar

4
@AlexanderBaltasar, 맞습니다. 유용 해 보이지만 데이터베이스와 상호 작용하기 위해 Python 코드를 사용하지 않습니다. 그 질문에 대한 의견을 참조하십시오.
Ben

11

이것은 간단하며 배치 모드 또는 출력 파일이 필요하지 않은 모든 항목에서 작동합니다.

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

from your_table where etc;

설명:

  1. 교체 "와 함께 ""각 분야에서 ->replace(field1, '"', '""')
  2. 각 결과를 따옴표로 묶으십시오-> concat('"', result1, '"')
  3. 인용 된 각 결과 사이에 쉼표를 넣으십시오-> concat_ws(',', quoted1, quoted2, ...)

그게 다야!


1
참고 NULL값으로 생략 될 concat_ws()열 부정합의 결과. 이것을 피하려면, 대신 빈 문자열을 사용하십시오 : IFNULL(field, '')(또는 다른 것을 표현하기 위해 사용하는 것 NULL)
Marco Roy

10

위의 답변 대신 CSV 엔진을 사용하는 MySQL 테이블을 가질 수 있습니다.

그런 다음 하드 디스크에 파일을 저장하면 처리하지 않고 복사 할 수있는 항상 CSV 형식으로됩니다.


1
파일 크기 / 쓰기 / 읽기 / 등의 측면에서 이것의 한계는 무엇입니까?
Zach Smith

8

이전 답변을 확장하기 위해 다음 단일 라이너는 단일 테이블을 탭으로 구분 된 파일로 내 보냅니다. 매일 데이터베이스를 내보내는 자동화에 적합합니다.

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    

4
CSV로 변환하려면mysql -B -D mydatabase -e 'select * from mytable' | sed -e 's/\t/,/g'
DSimon

7
sed -e 's/\t/,/g'데이터에 쉼표 나 탭이 포함되어 있지 않은 경우에만 사용하는 것이 안전합니다.
awatts

7

user7610을 기반으로하는 가장 좋은 방법입니다. 로 mysql outfile파일 소유권 및 덮어 쓰기 문제의 60 분이 있었다.

시원하지는 않지만 5 분 안에 작동했습니다.

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

<?php

$server = $argv[1];
$user = $argv[2];
$password = $argv[3];
$db = $argv[4];
$table = $argv[5];

mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db($db) or die(mysql_error());

// fetch the data
$rows = mysql_query('SELECT * FROM ' . $table);
$rows || die(mysql_error());


// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');

// output the column headings

$fields = [];
for($i = 0; $i < mysql_num_fields($rows); $i++) {
    $field_info = mysql_fetch_field($rows, $i);
    $fields[] = $field_info->name;
}
fputcsv($output, $fields);

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

?>

1
멋지고 깨끗하며 빠르게 작동합니다.이 환경에서 PHP를 실행할 수 있다면 훌륭한 솔루션입니다!
John Fiala

7

또한 Bash 명령 줄에서 쿼리를 수행하는 tr경우 기본 탭을 임의의 구분 기호로 대체하는 데 명령을 사용할 수 있다고 생각합니다 .

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


5

내가하는 일은 다음과 같습니다.

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로 변환하는 작업을 훌륭하게 수행합니다.


대단하다. 약간의 개선은 숫자를 제외한 모든 것을 인용하는 것일 수 있습니다 perl -F"\t" -lane 'print join ",", map {s/"/""/g; /^\d+(?:\.\d+)?$/ ? $_ : qq("$_")} @F '– 당신은 인용하지 않을 것입니다1.2.3
artfulrobot

5

정확히 CSV 형식은 아니지만 tee MySQL 클라이언트의 명령 을 사용하여 출력을 로컬 파일 에 저장할 수 있습니다 .

tee foobar.txt
SELECT foo FROM bar;

을 사용하여 비활성화 할 수 있습니다 notee.

문제 SELECT … INTO OUTFILE …; 는 서버에서 파일을 쓸 수있는 권한이 필요하다는 것입니다.


.txt 대신 .csv 확장자를 사용하는 경우 알아야 할 서식 문제가 있습니까?
datalifenyc

@myidealab 포맷 문제는 쉼표 등이 이스케이프되지 않아 발생합니다. CSV는 일반 텍스트 형식이므로 확장명을 바꾸는 것만으로 서식 문제가 없습니다.
jkmartindale

3

Tim이 게시 한 솔루션을 사용하여 프로세스를 용이하게하기 위해이 bash 스크립트를 만들었습니다 (루트 비밀번호가 요청되었지만 다른 사용자를 요청하도록 스크립트를 쉽게 수정할 수 있습니다).

#!/bin/bash

if [ "$1" == "" ];then
    echo "Usage: $0 DATABASE TABLE [MYSQL EXTRA COMMANDS]"
    exit
fi

DBNAME=$1
TABLE=$2
FNAME=$1.$2.csv
MCOMM=$3

echo "MySQL password:"
stty -echo
read PASS
stty echo

mysql -uroot -p$PASS $MCOMM $DBNAME -B -e "SELECT * FROM $TABLE;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > $FNAME

database.table.csv 라는 파일을 생성합니다.


3

서버에 PHP를 설정 한 경우 mysql2csv 를 사용 하여 임의의 mysql 쿼리에 대한 (실제로 유효한) CSV 파일을 내보낼 수 있습니다 . MySQL에서 내 답변 보기 -SELECT * INTO OUTFILE LOCAL?좀 더 컨텍스트 / 정보를 위해.

옵션 이름을 유지하려고 mysql했으므로 --file--query옵션 을 제공하기에 충분해야합니다 .

./mysql2csv --file="/tmp/result.csv" --query='SELECT 1 as foo, 2 as bar;' --user="username" --password="password"

mysql2csv통해 "설치"

wget https://gist.githubusercontent.com/paslandau/37bf787eab1b84fc7ae679d1823cf401/raw/29a48bb0a43f6750858e1ddec054d3552f3cbc45/mysql2csv -O mysql2csv -q && (sha256sum mysql2csv | cmp <(echo "b109535b29733bd596ecc8608e008732e617e97906f119c66dd7cf6ab2865a65  mysql2csv") || (echo "ERROR comparing hash, Found:" ;sha256sum mysql2csv) ) && chmod +x mysql2csv

(요지의 내용을 다운로드하고 체크섬을 확인하여 실행 가능하게하십시오).


3

나를 위해 일한 것 :

SELECT *
FROM students
WHERE foo = 'bar'
LIMIT 0,1200000
INTO OUTFILE './students-1200000.csv'
FIELDS TERMINATED BY ',' ESCAPED BY '"'
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';

이 스레드의 솔루션 중 어느 것도 내 특별한 경우에 효과가 없었습니다. 열 중 하나 안에 꽤 json 데이터가 있었으므로 csv 출력에서 ​​엉망이되었습니다. 비슷한 문제를 가진 사람들은 대신 \ r \ n으로 끝나는 줄을 시도하십시오.

Microsoft Excel로 CSV를 열려고하는 사람들에게 또 다른 문제는 단일 셀이 보유 할 수있는 32,767 자의 제한이 있다는 것입니다. 문제가있는 열의 레코드를 식별하려면 아래 쿼리를 사용하십시오. 그런 다음 해당 레코드를 자르거나 원하는대로 처리 할 수 ​​있습니다.

SELECT id,name,CHAR_LENGTH(json_student_description) AS 'character length'
FROM students
WHERE CHAR_LENGTH(json_student_description)>32767;

2

secure-file-priv그때 오류가 발생하면 대상 파일 위치 C:\ProgramData\MySQL\MySQL Server 8.0\Uploads를 옮긴 후 쿼리 후

SELECT * FROM attendance INTO OUTFILE 'C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\FileName.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

작동하지 않으면 \쿼리에서 다음으로 변경 (backsplash)해야합니다./ (forwardsplash)

그리고 그것은 작동합니다!

예:

OUTFILE 'C : / ProgramData / MySQL / MySQL Server 8.0 / Uploads / FileName.csv'에 출석 선택 * ','에 의해 종료 된 필드 '' '에 의해 종료 된 행'\ n ';

성공적인 쿼리를 실행할 때마다 매번 새로운 csv 파일이 생성됩니다! 좋아?


1

https://stackoverflow.com/a/5395421/2841607 에서 영감을 얻은 CSV 덤프에 대한 간단한 쿼리를 수행하는 작은 bash 스크립트 .

#!/bin/bash

# $1 = query to execute
# $2 = outfile
# $3 = mysql database name
# $4 = mysql username

if [ -z "$1" ]; then
    echo "Query not given"
    exit 1
fi

if [ -z "$2" ]; then
    echo "Outfile not given"
    exit 1
fi

MYSQL_DB=""
MYSQL_USER="root"

if [ ! -z "$3" ]; then
    MYSQL_DB=$3
fi

if [ ! -z "$4" ]; then
    MYSQL_USER=$4
fi

if [ -z "$MYSQL_DB" ]; then
    echo "Database name not given"
    exit 1
fi

if [ -z "$MYSQL_USER" ]; then
    echo "Database user not given"
    exit 1
fi

mysql -u $MYSQL_USER -p -D $MYSQL_DB -B -s -e "$1" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > $2
echo "Written to $2"

1

다음 bash 스크립트가 나를 위해 작동합니다. 또한 요청 된 테이블의 스키마를 선택적으로 가져옵니다.

#!/bin/bash
#
# export mysql data to CSV
#/programming/356578/how-to-output-mysql-query-results-in-csv-format
#

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'
red='\033[0;31m'
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}


#
# error
#
# show the given error message on stderr and exit
#
#   params:
#     1: l_msg - the error message to display
#
error() {
  local l_msg="$1"
  # use ansi red for error
  color_msg $red "Error:" 1>&2
  color_msg $red "\t$l_msg" 1>&2
  usage
}

#
# display usage 
#
usage() {
  echo "usage: $0 [-h|--help]" 1>&2
  echo "               -o  | --output      csvdirectory"    1>&2
  echo "               -d  | --database    database"   1>&2
  echo "               -t  | --tables      tables"     1>&2
  echo "               -p  | --password    password"   1>&2
  echo "               -u  | --user        user"       1>&2
  echo "               -hs | --host        host"       1>&2
  echo "               -gs | --get-schema"             1>&2
  echo "" 1>&2
  echo "     output: output csv directory to export mysql data into" 1>&2
  echo "" 1>&2
  echo "         user: mysql user" 1>&2
  echo "     password: mysql password" 1>&2
  echo "" 1>&2
  echo "     database: target database" 1>&2
  echo "       tables: tables to export" 1>&2
  echo "         host: host of target database" 1>&2
  echo "" 1>&2
  echo "  -h|--help: show help" 1>&2
  exit 1
}

#
# show help 
#
help() {
  echo "$0 Help" 1>&2
  echo "===========" 1>&2
  echo "$0 exports a csv file from a mysql database optionally limiting to a list of tables" 1>&2
  echo "   example: $0 --database=cms --user=scott --password=tiger  --tables=person --output person.csv" 1>&2
  echo "" 1>&2
  usage
}

domysql() {
  mysql --host $host -u$user --password=$password $database
}

getcolumns() {
  local l_table="$1"
  echo "describe $l_table" | domysql | cut -f1 | grep -v "Field" | grep -v "Warning" | paste -sd "," - 2>/dev/null
}

host="localhost"
mysqlfiles="/var/lib/mysql-files/"

# parse command line options
while true; do
  #echo "option $1"
  case "$1" in
    # options without arguments
    -h|--help) usage;;
    -d|--database)     database="$2" ; shift ;;
    -t|--tables)       tables="$2" ; shift ;;
    -o|--output)       csvoutput="$2" ; shift ;;
    -u|--user)         user="$2" ; shift ;;
    -hs|--host)        host="$2" ; shift ;;
    -p|--password)     password="$2" ; shift ;;
    -gs|--get-schema)  option="getschema";; 
    (--) shift; break;;
    (-*) echo "$0: error - unrecognized option $1" 1>&2; usage;;
    (*) break;;
  esac
  shift
done

# checks
if [ "$csvoutput" == "" ]
then
  error "ouput csv directory not set"
fi
if [ "$database" == "" ]
then
  error "mysql database not set"
fi
if [ "$user" == "" ]
then
  error "mysql user not set"
fi
if [ "$password" == "" ]
then
  error "mysql password not set"
fi

color_msg $blue "exporting tables of database $database"
if [ "$tables" = "" ]
then
tables=$(echo "show tables" | domysql)
fi

case $option in
  getschema) 
   rm $csvoutput$database.schema
   for table in $tables
   do
     color_msg $blue "getting schema for $table"
     echo -n "$table:" >> $csvoutput$database.schema
     getcolumns $table >> $csvoutput$database.schema
   done  
   ;;
  *)
for table in $tables
do
  color_msg $blue "exporting table $table"
  cols=$(grep "$table:" $csvoutput$database.schema | cut -f2 -d:)
  if [  "$cols" = "" ]
  then
    cols=$(getcolumns $table)
  fi
  ssh $host rm $mysqlfiles/$table.csv
cat <<EOF | mysql --host $host -u$user --password=$password $database 
SELECT $cols FROM $table INTO OUTFILE '$mysqlfiles$table.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
EOF
  scp $host:$mysqlfiles/$table.csv $csvoutput$table.csv.raw
  (echo "$cols"; cat $csvoutput$table.csv.raw) > $csvoutput$table.csv
  rm $csvoutput$table.csv.raw
done
  ;;
esac

1

나는 같은 문제가 발생했으며 RDS이기 때문에 Paul의 답변 은 선택 사항이 아닙니다. 데이터에 쉼표 및 탭이 포함되어 있으므로 탭을 쉼표로 바꾸지 못했습니다. mysql-client의 드롭 인 대안 인 mycli--csv플래그가 있는 상자에서 CSV 출력을 지원 한다는 것을 알았습니다.

mycli db_name --csv -e "select * from flowers" > flowers.csv

1

파일을 내보내려고 할 때이 오류가 발생하는 경우

오류 1290 (HY000) : MySQL 서버가 --secure-file-priv 옵션으로 실행 중이므로이 명령문을 실행할 수 없습니다.

이 오류를 해결할 수 없습니다. 이 파이썬 스크립트를 실행하여 한 가지 작업을 수행 할 수 있습니다

import mysql.connector
import csv

con = mysql.connector.connect(
    host="localhost",
    user="root",
    passwd="Your Password"
)

cur = con.cursor()

cur.execute("USE DbName")
cur.execute("""
select col1,col2 from table
where <cond>
""")

with open('Filename.csv',mode='w') as data:
    fieldnames=["Field1","Field2"]
    writer=csv.DictWriter(data,fieldnames=fieldnames)
    writer.writeheader()
    for i in cur:
        writer.writerow({'Field1':i[0],'Field2':i[1]})

스택 오버플로에 오신 것을 환영합니다! 이것은 질문에 대답하지 않습니다. stackoverflow.com/help/how-to-answer를 검토하십시오 .
stephenwade

0

사용중인 컴퓨터에 PHP가 설치되어 있으면 PHP 스크립트를 작성하여이를 수행 할 수 있습니다. PHP를 설치하려면 MySQL 확장이 설치되어 있어야합니다.

명령 행에서 다음과 같이 PHP 인터프리터를 호출 할 수 있습니다.

php --php-ini path/to/php.ini your-script.php

--php-iniMySQL 확장을 가능하게하는 자체 PHP 구성을 사용해야 할 수도 있기 때문에 스위치를 포함하고 있습니다. PHP 5.3.0 이상에서는 기본적으로 해당 확장이 활성화되어 있으므로 더 이상 구성을 사용하여 확장 할 필요가 없습니다.

그런 다음 일반 PHP 스크립트와 같이 내보내기 스크립트를 작성할 수 있습니다.

<?php
    #mysql_connect("localhost", "username", "password") or die(mysql_error());
    mysql_select_db("mydb") or die(mysql_error());

    $result = mysql_query("SELECT * FROM table_with_the_data p WHERE p.type = $typeiwant");

    $result || die(mysql_error());

    while($row = mysql_fetch_row($result)) {
      $comma = false;
      foreach ($row as $item) {

        # Make it comma separated
        if ($comma) {
          echo ',';
        } else {
          $comma = true;
        }

        # Quote the quotes
        $quoted = str_replace("\"", "\"\"", $item);

        # Quote the string
        echo "\"$quoted\"";
      }
        echo "\n";
    }
?>

이 방법의 장점은 개행을 포함하는 텍스트가있는 varchar 및 텍스트 필드에 문제가 없다는 것입니다. 해당 필드는 올바르게 인용되며 필드의 개행은 레코드 구분 기호가 아닌 텍스트의 일부로 CSV 리더에서 해석됩니다. 그것은 나중에 sed 로 수정하기 어려운 것입니다 .


1
불필요하게 복잡하지는 않지만 약간 더 많은 작업이 필요하지만 올바른 방향으로 진행되는 유일한 솔루션입니다. CSV는 처음 나타나는 것보다 훨씬 복잡하며 다양한 실수를했습니다. 예를 들어 원본의 백 슬래시. CSV에 쓰는 모든 문제를 해결 한 라이브러리를 사용하는 것이 좋습니다.
mc0e

@ mc0e 일반적으로 따옴표를 두 배로 늘리거나 따옴표를 이스케이프 처리합니다. 따옴표를 두 배로하기로 결정했기 때문에 이스케이프 문자가 필요하지 않습니다. 소프트웨어마다 CSV 세부 정보에 대한 아이디어가 다릅니다. 예를 들어 MySQL의 LOAD DATA는 실제로 \를 이스케이프 문자로 취급하지만 Open Office Calc는 그렇지 않습니다. 답을 쓸 때 데이터를 스프레드 시트로 내보내고있었습니다.
user7610

1
내보낼 필요했던 내 코드 핸들의 모든 것을 하루에 데이터 세트 등을) 당신의 대답은 또한 올바른 방향으로의 한 단계입니다 만,이 말한다 최초의 주석으로, 그것은 1)로 직접 스크립트에서 SQL 데이터베이스에 연결해야 뿐만 아니라 2) 적절한 CSV 라이브러리를 사용하십시오.
user7610
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.