Включити заголовки під час використання 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.