Включити заголовки під час використання 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, а також відповідь matt, щоб швидко отримати всі ColName1, ColName2 тощо. Дуже корисні додатки до цієї чудової відповіді!
— Андрій Т

1
Ця відповідь здається правильною, пекло, я навіть її майже наосліп використовував на своєму сервері розробників ... Без заголовків стовпців потрібно скинути 240 мільйонів рядків близько 50 секунд. Завдяки цьому UNION ALL сервер потрапляє у великі проблеми, намагаючись зробити тимчасовий стіл перед тим, як скинути все, вже минуло 10 хвилин і все ще чекає, поки тимчасова таблиця буде записана на диск! Будьте в курсі цього! Ви, звичайно, вважаєте за краще додати назви стовпців іншим способом, навіть якщо це означає відкриття файлу після іншої мови програмування.
— Салькетер

Це, здається, працює лише в тому випадку, якщо всі стовпці YourTable є символьним типом даних, що має сенс. В іншому випадку ви отримуєте непотрібну помилку: "Використовувані оператори SELECT мають різну кількість стовпців".
— TheBamf

1
Це одна з причин, чому я розглядаю можливість переходу на іншу СУБД.
— e18r

85

Рішення, яке надає Джо Стеанеллі, працює, але складати список колонок незручно, коли задіяні десятки чи сотні стовпців. Ось як отримати список стовпців таблиці 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

Тепер ви можете скопіювати і вставити отриманий рядок як перший вислів у методі Джо.


2
Це повертає всі об'єднані стовпці в одному полі. Я не можу об'єднати це з іншим оператором select, який повертає кілька полів. Це дійсно корисно для отримання рядка, який я можу скопіювати та вставити як заголовок мого обходу.
— tmoore82

1
Ідея полягає в тому, щоб скопіювати отримане єдине поле і вставити його у свій виступ UNION, а не вводити вручну колонку1, колонку2 тощо при використанні методу Джо (прийнята відповідь), щоб ви могли швидше отримати список стовпців!
— Ендрю Т

Я шукав експорту всіх своїх схем таблиці / полів. Ця відповідь у поєднанні з прийнятою зробила трюк!
— Ремі Бретон

@ Кріс ORDER BY ORDINAL_POSITIONручки , які
— матовий

1
ЗАМОВЛЕННЯ ORDINAL_POSITION має бути частиною виклику GROUP_CONCAT (), як вGROUP_CONCAT(CONCAT('"',COLUMN_NAME,'"') order BY ORDINAL_POSITION)
— Апулей

15

Для складного вибору з ЗАМОВЛЕННЯ Я використовую наступне:

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 ВСЕ замовлення стовпця 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;

Дякую лучеку.


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; інших макетів, запропонованих у цій темі, не зробили.
— ПрограмістDan

Чомусь з'являється заголовок внизу, але добре працює, щоб повернути цю вершину в додатку для електронних таблиць, дивно, але ура
— Дмитро БД

Я також затримався з використанням mariaDB. з витягом всього 100 відводів, це було на 14 секунд швидше, ніж запуск прийнятої відповіді. Перший пас із прийнятим: Query OK, 100 rows affected (14.72 sec) Другий пас із вашимQuery OK, 101 rows affected (0.00 sec)
— Каспер Вілкс

6

Я просто роблю 2 запити, по-перше, щоб отримати вихідний запит (обмеження 1) з іменами стовпців (відсутність жорсткого коду, проблеми з Joins, Order by, користувацькі назви стовпців тощо), а по-друге, щоб зробити сам запит і об'єднати файли в один 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

Я зіткнувся з подібною проблемою під час виконання запиту mysql на великих таблицях у NodeJS. Підхід, який я дотримувався для включення заголовків у свій файл 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. Додайте заголовки стовпців до файлу, створеного на кроці 1, за допомогою npm-пакету prepend-file

Виконання кожного кроку контролювалося, використовуючи обіцянки в NodeJS.


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 додасть стовпець 'row.names' на початку CSV, тому ви захочете відкинути це, якщо вам потрібно покластися на CSV для відтворення таблиці.


2

Отже, якщо всі стовпці в my_tableсимвольному типі даних , ми можемо об'єднати головні відповіді (Джо, мат та злагук) разом, щоб автоматично додавати заголовок в одному простому запиті 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 мають різну кількість стовпців". Сер
— Боуї Лю

1

Я думаю, що якщо ви будете використовувати UNION, це спрацює:

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

Я не знаю, як безпосередньо вказати заголовки синтаксисом INTO OUTFILE.


1
СПІЛЬ ВСЕ було б безпечніше і швидше.
— токсалот

1

Насправді ви можете змусити його працювати навіть за допомогою ЗАМОВЛЕННЯ.

Просто потрібна певна хитрість у порядку за заявою - ми використовуємо оператор справи і заміняємо значення заголовка на якесь інше значення, яке гарантовано сортується першим у списку (очевидно, це залежить від типу поля та сортуєш 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

Оскільки функціональність "включити заголовки" ще не є вбудованою, і для більшості "рішень" тут потрібно вводити назви стовпців вручну та / або навіть не брати до уваги, я рекомендую обійти проблему .

  • Найкраща альтернатива, яку я знайшов поки що, - це використання гідного інструменту (я використовую HeidiSQL ).
    Поставте свій запит, виберіть сітку, клацніть правою кнопкою миші та експортуйте у файл. У ньому були всі необхідні варіанти для чистого експорту, і ans повинен задовольнити більшість потреб.

  • У цій же ідеї підхід user3037511 працює чудово, і його можна легко автоматизувати .
    Просто запустіть свій запит у якомусь командному рядку, щоб отримати заголовки. Ви можете отримати дані за допомогою SELECT INTO OUTFILE ... або запустивши запит без обмежень, ваш вибір.

    Зауважте, що переадресація виводу у файл працює як шарм для Linux та Windows.


Це змушує мене підкреслити, що 80% часу, коли я хочу використовувати SELECT FROM INFILE або SELECT INTO OUTFILE, я закінчую використання чогось іншого через деякі обмеження (тут відсутність "параметрів заголовків" на AWS-RDS, відсутні права тощо).

Отже, я не точно відповісти на ор в питанні ... але він повинен відповісти на його потреби :)
EDIT: і насправді відповісти на його питання: немає
Станом на 2017-09-07, ви просто не може включати в себе заголовки , якщо вам дотримуйтесь команди SELECT INTO OUTFILE
: |


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

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
Досить рішення, чи варто говорити. Прийняли його в моїх цілях. Дякую!
— Денис Кулагін

0

Я хотів би додати відповідь, яку надав Сангам Белоз. Ось його код:

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 одного недостатньо для цього просто. Нижче представлений скрипт 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.


-1
Виберіть 'ColName1', 'ColName2', 'ColName3'
СОЮЗ ВСІХ
Виберіть ColName1, ColName2, ColName3
    З Твоєї таблиці
    В НАЗАД 'c: \\ datasheet.csv' ПОЛИ, ЗАВЕРШЕНІ В ',' ОПЦІОНАЛЬНО ЗАКРІПЛЕНО '' 'ЛІНІЇ, ЗАКРІНЛЕНІ' \ n ' 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.