Respostas:
Você mesmo teria que codificar esses cabeçalhos. Algo como:
SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT ColName1, ColName2, ColName3
FROM YourTable
INTO OUTFILE '/path/outfile'
A solução fornecida por Joe Steanelli funciona, mas fazer uma lista de colunas é inconveniente quando dezenas ou centenas de colunas estão envolvidas. Veja como obter a lista da tabela coluna my_table em my_schema .
-- 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
Agora você pode copiar e colar a linha resultante como primeira instrução no método de Joe.
ORDER BY ORDINAL_POSITION
cuida disso
GROUP_CONCAT(CONCAT('"',COLUMN_NAME,'"') order BY ORDINAL_POSITION)
Para a seleção complexa com ORDER BY, eu uso o seguinte:
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';
Você pode usar a declaração preparada com a resposta de Lucek e exportar dinamicamente a tabela com o nome das colunas em 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;
Obrigado, lucek.
Isso permitirá que você tenha colunas ordenadas e / ou um limite
SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT * from (SELECT ColName1, ColName2, ColName3
FROM YourTable order by ColName1 limit 3) a
INTO OUTFILE '/path/outfile';
Query OK, 100 rows affected (14.72 sec)
Segundo passe com o seuQuery OK, 101 rows affected (0.00 sec)
Eu simplesmente faço 2 consultas, primeiro para obter a saída da consulta (limite 1) com nomes de coluna (sem hardcode, sem problemas com associações, ordenar por, nomes de colunas personalizados, etc) e, em segundo lugar, para fazer a própria consulta e combinar arquivos em um CSV Arquivo:
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
Eu enfrentei um problema semelhante ao executar a consulta mysql em grandes tabelas no NodeJS. A abordagem que segui para incluir cabeçalhos em meu arquivo CSV é a seguinte
Use a consulta OUTFILE para preparar o arquivo sem cabeçalhos
SELECT * INTO OUTFILE [FILE_NAME] FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED
BY '\"' LINES TERMINATED BY '\n' FROM [TABLE_NAME]
Buscar cabeçalhos de coluna para a tabela usada no ponto 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
Anexe os cabeçalhos das colunas ao arquivo criado na etapa 1 usando o pacote npm prepend -file
A execução de cada etapa foi controlada por meio de promessas em NodeJS.
Este é um cheat alternativo se você estiver familiarizado com Python ou R, e sua tabela cabe na memória.
Importe a tabela SQL para Python ou R e, em seguida, exporte de lá como um CSV e você obterá os nomes das colunas, bem como os dados.
Veja como faço isso usando R, requer a biblioteca 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')
É uma espécie de trapaça, mas descobri que essa era uma solução rápida quando meu número de colunas era muito longo para usar o método concat acima. Nota: R adicionará uma coluna 'row.names' no início do CSV, então você vai querer descartá-la se precisar contar com o CSV para recriar a tabela.
Portanto, se todas as colunas em my_table
são um tipo de dados de caractere , podemos combinar as principais respostas (por Joe, matt e evilguc) juntas, para obter o cabeçalho adicionado automaticamente em uma consulta SQL 'simples', por exemplo
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';
onde as últimas linhas tornam a saída csv.
Observe que isso pode ser lento se my_table
for muito grande.
Na verdade, você pode fazer isso funcionar mesmo com um ORDER BY.
Só precisa de alguns truques na ordem por instrução - usamos uma instrução case e substituímos o valor do cabeçalho por algum outro valor que é garantido para classificar primeiro na lista (obviamente, isso depende do tipo de campo e se você está classificando ASC ou DESC)
Digamos que você tenha três campos, nome (varchar), is_active (bool), date_something_happens (date), e deseja classificar os dois segundos em ordem decrescente:
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
Uma vez que a funcionalidade de 'incluir-cabeçalhos' ainda não parece estar embutida, e a maioria das "soluções" aqui precisam digitar os nomes das colunas manualmente e / ou nem mesmo levar as junções em consideração, eu recomendo contornar o problema .
A melhor alternativa que encontrei até agora é usar uma ferramenta decente (eu uso o HeidiSQL ).
Coloque sua solicitação, selecione a grade, basta clicar com o botão direito e exportar para um arquivo. Ele tem todas as opções necessárias para uma exportação limpa, e deve atender à maioria das necessidades.
Na mesma ideia, a abordagem do user3037511 funciona bem e pode ser automatizada facilmente .
Basta iniciar sua solicitação com alguma linha de comando para obter seus cabeçalhos. Você pode obter os dados com um SELECT INTO OUTFILE ... ou executando sua consulta sem limite, à sua escolha.
Observe que o redirecionamento de saída para um arquivo funciona perfeitamente no Linux E no Windows.
Isso me faz querer destacar que 80% das vezes, quando eu quero usar SELECT FROM INFILE ou SELECT INTO OUTFILE, acabo usando outra coisa devido a algumas limitações (aqui, a ausência de 'opções de cabeçalhos', em um AWS-RDS, os direitos ausentes e assim por diante.)
Por isso, eu não exatamente responder à da op pergunta ... mas deve responder a necessidades :)
EDIT: e para realmente responder a sua pergunta: há
a partir de 2017/09/07, você simplesmente não pode incluir cabeçalhos se continue com o comando SELECT INTO OUTFILE : |
um exemplo do meu sensor de nome de tabela de banco de dados com colunas (id, tempo, unidade)
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
Eu estava escrevendo meu código em PHP e tive alguns problemas para usar as funções concat e união, e também não usei variáveis SQL, de qualquer maneira que fiz isso funcionar, aqui está o meu código:
//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);
Esta é uma maneira de obter os títulos dos cabeçalhos dos nomes das colunas de forma dinâmica.
/* 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;
Eu gostaria de acrescentar algo à resposta fornecida por Sangam Belose. Aqui está seu código:
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
No entanto, se você não configurou seu "secure_file_priv"
nas variáveis, pode não funcionar. Para isso, verifique a pasta definida nessa variável:
SHOW VARIABLES LIKE "secure_file_priv"
A saída deve ser semelhante a esta:
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)
Você pode alterar essa variável ou alterar a consulta para enviar o arquivo para o caminho padrão mostrado.
O MySQL sozinho não é suficiente para fazer isso de forma simples. Abaixo está um script PHP que produzirá colunas e dados em CSV.
Insira o nome do banco de dados e as tabelas perto do topo.
<?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() );
}
?>
Você precisará que este seja o diretório para o qual deseja enviar a saída. O MySQL precisa ter a capacidade de gravar no diretório.
$path = '/var/lib/mysql/' . $tbl . '.csv';
Você pode editar as opções de exportação de CSV na consulta:
INTO OUTFILE "' . $path . '"
FIELDS TERMINATED BY ","
ENCLOSED BY "\""
LINES TERMINATED BY "\n"'
No final, há uma chamada exec para GZip, o CSV.
SELECIONE 'ColName1', 'ColName2', 'ColName3' UNION ALL SELECIONE ColName1, ColName2, ColName3 DE YourTable INTO OUTFILE 'c: \\ datasheet.csv' CAMPOS TERMINADOS POR ',' OPCIONALMENTE CONCLUÍDO POR '"' LINHAS TERMINADAS POR '\ n'
ORDER BY
naSELECT
cláusula. A linha de cabeçalho pode estar em qualquer lugar no arquivo gerado, dependendo do pedido.