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 BYSELECT節内にある場合は機能しません。ヘッダー行は、順序に応じて、生成されたファイルのどこにあってもかまいません。
コイル2014年

ORDER BYの使用に関するアイデアについては、以下のいくつかの回答を参照してください。また、すべてのColName1、ColName2などをすばやく取得する方法については、マットの回答もご覧ください。この素晴らしい回答の非常に便利なアドオン!
アンドリューT

1
この答えはほぼ正しいようですが、私は開発サーバーでほとんど盲目的にそれを使用しました...列ヘッダーがないと、2億4000万行をダンプするのに約50秒かかります。このUNION ALLを使用すると、サーバーはすべてをダンプする前に一時テーブルを作成しようとするときに大きな問題に直面します。10分以上経過し、一時テーブルがディスクに書き込まれるのを待っています!気をつけて!別のプログラミング言語でファイルを開いた後でも、別の方法で列名を追加することをお勧めします。
Salketer 2016年

これは、YourTableのすべての列が文字データ型である場合にのみ機能するように見えますが、これは意味があります。そうしないと、「使用されたSELECTステートメントの列数が異なります」という役に立たないエラーが発生します。
TheBamf

1
これが、別のDBMSへの切り替えを検討している理由の1つです。
e18r 2016

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
これは、1つのフィールドに連結されたすべての列を返します。複数のフィールドを返す別のselectステートメントでそれを結合することはできません。これは、コピーして、出力ファイルのヘッダーとして貼り付けることができる行を取得するのに非常に役立ちます。
tmoore82 14年

1
Joeの方法(承認された回答)を使用する場合は、結果の単一フィールドをコピーしてUNIONステートメントに貼り付け、column1、column2などを手動で入力する代わりに、列のリストをすばやく取得できます。
Andrew T

すべてのテーブル/フィールドスキーマをエクスポートしようとしていました。この答えと受け入れられた答えを組み合わせることでトリックが実現しました!
レミブルトン

@ChrisがORDER BY ORDINAL_POSITION対応
マット

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

このソリューションは、2番目の(複雑な)クエリを注文するときにうまく機能します。この方法で行わないと、最初の列が順序付けられることになり、これは望ましくありません。素敵な提案@evilguc!
アーロン、

UNION ALLを実行した後、私と一緒に動作しませんでした
。id

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

なんらかの理由で下部のヘッダーをポップしますが、スプレッドシートアプリの上部にそれをポップして正常に機能します。奇妙ですが、歓声
Dmitri DB

私もmariaDBを使用して立ち往生しています。リードを100件抽出しただけで、これは承認された回答を実行するよりも14秒以上高速でした。承認済みの最初のパス:Query OK, 100 rows affected (14.72 sec) あなたの2番目のパスQuery OK, 101 rows affected (0.00 sec)
キャスパーウィルクス

6

私は単純に2つのクエリを作成します。1つは列名(ハードコードなし、Jo​​in、Order by、カスタム列名などの問題はありません)でクエリ出力(制限1)を取得し、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

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による)を組み合わせて、1つの「単純な」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 2017

1

UNIONを使えばうまくいくと思います:

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

INTO OUTFILE構文でヘッダーを直接指定する方法がわかりません。


1
UNION ALLはより安全で高速です。
toxalot 2013

1

実際には、ORDER BYを使用しても機能させることができます。

order byステートメントにちょっとした工夫が必要です-caseステートメントを使用して、ヘッダー値をリストの最初にソートされることが保証されている他の値に置き換えます(明らかに、これはフィールドのタイプと、ASCまたはDESC)

name(varchar)、is_active(bool)、date_something_happens(date)の3つのフィールドがあり、2番目の2つのフィールドを降順に並べ替えるとします。

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を使用しています)。
    リクエストを入れ、グリッドを選択し、右クリックしてファイルにエクスポートします。クリーンなエクスポートに必要なすべてのオプションがあり、ansはほとんどのニーズを処理するはずです。

  • 同じ考えで、user3037511のアプローチはうまく機能し、簡単自動化できます。 ヘッダーを取得するには、
    コマンドラインでリクエストを起動するだけです。SELECT INTO OUTFILE ...を使用してデータを取得することも、無制限にクエリを実行して選択することもできます。

    ファイルへの出力リダイレクトは、LinuxとWindowsの両方でチャームのように機能することに注意してください。


これにより、その80%の時間を強調したいと思います。SELECTFROM INFILEまたはSELECT INTO OUTFILEを使用したい場合、他の何かを使用することになります。、いくつかの制限(ここでは、「ヘッダーオプション」がないため、 AWS-RDS、不足している権限など)。

したがって、私はopの質問に正確に答えていません...しかし、それは彼のニーズに答えるはずです:)
編集:そして実際に彼の質問に答えるには:いいえ
2017-09-07現在、ヘッダーを含めることはできませんSELECT INTO OUTFILEコマンドを使い続ける
:|


1

私のデータベーステーブル名の例センサcolums(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

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'、 'C​​olName2'、 'C​​olName3'
UNION ALL
SELECT ColName1、ColName2、ColName3
    YourTableから
    INTO OUTFILE 'c:\\ datasheet.csv' FIELDS TERMINATED BY '、' OPTIONALLY ENCLOSED BY '"' Lines TERMINATED BY '\ n' 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.