SELECT INTO OUTFILE을 사용할 때 헤더를 포함 하시겠습니까?


117

MySQL을 사용할 때 어떻게 든 헤더를 포함 할 수 INTO OUTFILE있습니까?

답변:


166

이러한 헤더를 직접 하드 코딩해야합니다. 다음과 같은 것 :

SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT ColName1, ColName2, ColName3
    FROM YourTable
    INTO OUTFILE '/path/outfile'

14
이 생길 경우 그러나 그것은 작동하지 않습니다 ORDER BY에있는 SELECT절. 헤더 행은 순서에 따라 생성 된 파일의 어느 위치 에나있을 수 있습니다.
COil

ORDER BY 사용에 대한 아이디어와 모든 ColName1, ColName2 등을 빠르게 얻는 방법에 대한 Matt의 답변은 아래 몇 가지 답변을 참조하십시오.이 훌륭한 답변에 대한 매우 유용한 추가 기능입니다!
Andrew T

1
이 대답은 옳은 것 같습니다. 제 개발 서버에서 거의 맹목적으로 사용했습니다 ... 열 헤더가 없으면 2 억 4 천만 줄을 덤프하는 데 약 50 초가 걸립니다. 이 UNION ALL을 사용하면 서버는 모든 것을 덤프하기 전에 임시 테이블을 시도하는 데 큰 문제를 겪고 있습니다. 이제 10 분이 넘었지만 여전히 임시 테이블이 디스크에 기록되기를 기다리고 있습니다! 그것에주의하십시오! 다른 프로그래밍 언어로 파일을 여는 것을 의미하더라도 열 이름을 다른 방법으로 추가하는 것이 좋습니다.
Salketer

이것은 YourTable의 모든 열이 문자 데이터 유형 인 경우에만 작동하는 것으로 보입니다. 그렇지 않으면 "사용 된 SELECT 문에 다른 수의 열이 있습니다."라는 도움이되지 않는 오류가 발생합니다.
TheBamf

1
이것이 다른 DBMS 로의 전환을 고려하는 이유 중 하나입니다.
e18r

85

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
단일 필드에 함께 연결된 모든 열을 반환합니다. 여러 필드를 반환하는 다른 select 문과 결합 할 수 없습니다. 이것은 내 outfile의 헤더로 복사하여 붙여 넣을 수있는 행을 얻는 데 정말 유용합니다.
tmoore82 2014

1
아이디어는 Joe의 방법 (허용되는 대답)을 사용할 때 결과 단일 필드를 복사하여 열 1, 열 2 등을 수동으로 입력하는 대신 UNION 문에 붙여 넣어 열 목록을 더 빨리 얻을 수 있도록하는 것입니다!
Andrew T

내 모든 테이블 / 필드 스키마를 내보내려고했습니다. 이 대답과 받아 들여진 대답이 트릭을했습니다!
Rémi Breton

@Chris ORDER BY ORDINAL_POSITION가 처리합니다
matt

1
ORDER BY ORDINAL_POSITION은 다음과 같이 GROUP_CONCAT () 호출의 일부 여야합니다.GROUP_CONCAT(CONCAT('"',COLUMN_NAME,'"') order BY ORDINAL_POSITION)
Apuleius

15

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

이 솔루션은 두 번째 (복잡한) 쿼리를 주문할 때 잘 작동합니다. 이런 식으로하지 않으면 첫 번째 열도 순서가 지정되어 바람직하지 않습니다. 좋은 제안 @evilguc!
아론

UNION ALL에게 id 컬럼의 순서를 수행 한 후, 나와 함께 작동하지 않았다가 엉망
모하 Kaleia을

6

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에게 감사합니다.


6

이렇게하면 열 및 / 또는 제한을 정렬 할 수 있습니다.

SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT * from (SELECT ColName1, ColName2, ColName3
    FROM YourTable order by ColName1 limit 3) a
    INTO OUTFILE '/path/outfile';

1
이 쿼리 레이아웃이 MariaDB 10.1에서도 작동했습니다. 이 스레드에서 제안 된 다른 레이아웃은 그렇지 않았습니다.
ProgrammerDan

어떤 이유로 바닥에 헤더를 팝 있지만, 스프레드 시트 응용 프로그램에서 위에 그 뒤로 팝, 이상한하지만 환호 잘 작동
드미트리 DB

나는 mariaDB도 사용하고 있습니다. 단 100 개의 리드 만 추출하면 허용 된 답변을 실행하는 것보다 14 초 이상 빠릅니다. 인정하는 최초의 패스 : Query OK, 100 rows affected (14.72 sec) 당신과 함께 두 번째 패스Query OK, 101 rows affected (0.00 sec)
캐스퍼 윌크스

6

두 개의 쿼리를 작성합니다. 먼저 열 이름 (하드 코드 없음, 조인, 정렬 기준, 사용자 지정 열 이름 등에 문제 없음)으로 쿼리 출력 (제한 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

5

NodeJS의 큰 테이블에서 mysql 쿼리를 실행하는 동안 비슷한 문제에 직면했습니다. 내 CSV 파일에 헤더를 포함하기 위해 따르는 접근 방식은 다음과 같습니다.

  1. OUTFILE 쿼리를 사용하여 헤더없이 파일 준비

        SELECT * INTO OUTFILE [FILE_NAME] FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED 
        BY '\"' LINES TERMINATED BY '\n' FROM [TABLE_NAME]
  2. 포인트 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
  3. prepend-file npm 패키지를 사용하여 1 단계에서 만든 파일에 열 헤더를 추가합니다.

각 단계의 실행은 NodeJS의 promise를 사용하여 제어되었습니다.


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은 CSV 시작 부분에 'row.names'열을 추가하므로 CSV에 의존하여 테이블을 다시 만들어야하는 경우 해당 열을 삭제하고 싶을 것입니다.


2

따라서의 모든 열 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이 매우 큰 경우 느릴 수 있습니다 .


"사용 된 SELECT 문에 열 수가 다릅니다"오류가 있습니다. 선생님
Bowei Liu

1

UNION을 사용하면 작동 할 것이라고 생각합니다.

select 'header 1', 'header 2', ...
union
select col1, col2, ... from ...

INTO OUTFILE 구문으로 헤더를 직접 지정하는 방법을 모르겠습니다.


1
UNION ALL 은 더 안전하고 빠릅니다.
toxalot

1

실제로 ORDER BY로도 작동하도록 만들 수 있습니다.

order by 문에서 약간의 속임수가 필요합니다. case 문을 사용하고 헤더 값을 목록에서 먼저 정렬되도록 보장되는 다른 값으로 대체합니다 (분명히 이것은 필드 유형과 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

1

'include-headers'기능은 아직 내장되어 있지 않은 것 같고 여기에있는 대부분의 "솔루션"은 열 이름을 수동으로 입력해야하며 조인도 고려하지 않아야합니다. 문제를 해결하십시오 .

  • 지금까지 찾은 최고의 대안은 괜찮은 도구를 사용하는 것입니다 (저는 HeidiSQL을 사용합니다 ).
    요청을 입력하고 그리드를 선택한 다음 마우스 오른쪽 버튼을 클릭하고 파일로 내 보냅니다. 깨끗한 내보내기에 필요한 모든 옵션이 있으며 대부분의 요구 사항을 처리해야합니다.

  • 같은 아이디어에서 user3037511의 접근 방식은 잘 작동하며 쉽게 자동화 할 수 있습니다 . 헤더를 얻으려면
    몇 가지 명령 줄로 요청을 시작 하면됩니다. SELECT INTO OUTFILE ...을 사용하여 데이터를 얻거나 제한없이 쿼리를 실행하여 선택할 수 있습니다.

    파일로의 출력 리디렉션은 Linux와 Windows 모두에서 매력처럼 작동합니다.


이것은 80 %의 시간 을 강조하고 싶습니다. SELECT FROM INFILE 또는 SELECT INTO OUTFILE을 사용하고 싶을 때 다른 것을 사용하게됩니다. 몇 가지 제한으로 인해 하게됩니다 (여기서는 '헤더 옵션'이 없습니다. AWS-RDS, 누락 된 권한 등)

따라서 나는 op의 질문에 정확히 대답하지는 않지만 그의 요구에해야합니다. :)
편집 : 그리고 실제로 그의 질문에 대답하려면 : 아니오
2017-09-07 현재, 당신은 헤더를 포함 할 수 없습니다. SELECT INTO OUTFILE 명령을 사용하십시오
.


1

컬럼 (id, time, unit)있는 데이터베이스 테이블 이름 센서 의 예

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

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);

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;

1
내가 말해야 할 상당한 해결책. 내 목적을 위해 채택했습니다. 감사!
Denis Kulagin

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)

이 변수를 변경하거나 쿼리를 변경하여 파일을 표시되는 기본 경로로 출력 할 수 있습니다.


0

MySQL만으로는 이것을 간단히 할 수 없습니다. 아래는 열과 데이터를 CSV로 출력하는 PHP 스크립트입니다.

상단 근처에 데이터베이스 이름과 테이블을 입력합니다.

<?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"'

마지막에 CSV GZip에 대한 exec 호출이 있습니다.


-1
SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
ColName1, ColName2, ColName3 선택
    YourTable에서
    INTO OUTFILE 'c : \\ datasheet.csv'필드는 ','로 종료되며, 선택적으로 ' "'로 종료 된 행은 '\ n'으로 종료됩니다. 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.