Réponses:
Vous devrez coder en dur ces en-têtes vous-même. Quelque chose comme:
SELECT 'ColName1', 'ColName2', 'ColName3'
UNION ALL
SELECT ColName1, ColName2, ColName3
FROM YourTable
INTO OUTFILE '/path/outfile'
La solution fournie par Joe Steanelli fonctionne, mais faire une liste de colonnes n'est pas pratique lorsque des dizaines ou des centaines de colonnes sont impliquées. Voici comment obtenir la liste des colonnes de la table my_table dans 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
Vous pouvez maintenant copier et coller la ligne résultante comme première instruction dans la méthode de Joe.
ORDER BY ORDINAL_POSITION
gère ça
GROUP_CONCAT(CONCAT('"',COLUMN_NAME,'"') order BY ORDINAL_POSITION)
Pour une sélection complexe avec ORDER BY, j'utilise ce qui suit:
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';
Vous pouvez utiliser l'instruction préparée avec la réponse de Lucek et exporter dynamiquement la table avec le nom des colonnes en 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;
Merci Lucek.
Cela vous permettra d'avoir des colonnes ordonnées et / ou une 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)
Deuxième laissez-passer avec le vôtreQuery OK, 101 rows affected (0.00 sec)
Je fais simplement 2 requêtes, d'abord pour obtenir la sortie de la requête (limite 1) avec les noms de colonnes (pas de code en dur, pas de problèmes avec les jointures, Trier par, les noms de colonnes personnalisés, etc.), et la seconde pour faire la requête elle-même et combiner les fichiers en un seul CSV fichier:
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
J'ai rencontré un problème similaire lors de l'exécution d'une requête mysql sur de grandes tables dans NodeJS. L'approche que j'ai suivie pour inclure les en-têtes dans mon fichier CSV est la suivante
Utilisez la requête OUTFILE pour préparer le fichier sans en-têtes
SELECT * INTO OUTFILE [FILE_NAME] FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED
BY '\"' LINES TERMINATED BY '\n' FROM [TABLE_NAME]
Récupérer les en-têtes de colonne pour le tableau utilisé au point 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
Ajoutez les en-têtes de colonne au fichier créé à l'étape 1 à l'aide du package npm prepend-file
L'exécution de chaque étape a été contrôlée à l'aide de promesses dans NodeJS.
C'est une triche alternative si vous êtes familier avec Python ou R, et votre table peut tenir dans la mémoire.
Importez la table SQL dans Python ou R, puis exportez-la au format CSV et vous obtiendrez les noms de colonnes ainsi que les données.
Voici comment je le fais en utilisant R, nécessite la bibliothèque 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')
C'est un peu une triche, mais j'ai trouvé que c'était une solution de contournement rapide lorsque mon nombre de colonnes était trop long pour utiliser la méthode concat ci-dessus. Remarque: R ajoutera une colonne 'row.names' au début du CSV, vous voudrez donc la supprimer si vous avez besoin de vous fier au CSV pour recréer la table.
Donc, si toutes les colonnes de my_table
sont un type de données caractère , nous pouvons combiner les réponses principales (de Joe, matt et evilguc) ensemble, pour obtenir l'en-tête ajouté automatiquement dans une requête SQL `` simple '', par exemple
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';
où les deux dernières lignes font la sortie csv.
Notez que cela peut être lent s'il my_table
est très volumineux.
En fait, vous pouvez le faire fonctionner même avec un ORDER BY.
Il faut juste quelques astuces dans l'ordre par instruction - nous utilisons une instruction case et remplaçons la valeur d'en-tête par une autre valeur dont le tri est garanti en premier dans la liste (cela dépend évidemment du type de champ et si vous triez ASC ou DESC)
Supposons que vous ayez trois champs, name (varchar), is_active (bool), date_something_happens (date), et que vous souhaitiez trier les deux seconds par ordre décroissant:
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
Étant donné que la fonctionnalité 'include-headers' ne semble pas encore intégrée et que la plupart des "solutions" ici doivent taper les noms des colonnes manuellement, et / ou ne même pas prendre en compte les jointures, je vous recommande de contourner le problème .
La meilleure alternative que j'ai trouvée jusqu'à présent est d'utiliser un outil décent (j'utilise HeidiSQL ).
Mettez votre demande, sélectionnez la grille, faites un simple clic droit et exportez vers un fichier. Il a toutes les options nécessaires pour une exportation propre et devrait gérer la plupart des besoins.
Dans la même idée, l'approche de user3037511 fonctionne bien et peut être automatisée facilement .
Lancez simplement votre requête avec une ligne de commande pour obtenir vos en-têtes. Vous pouvez obtenir les données avec un SELECT INTO OUTFILE ... ou en exécutant votre requête sans la limite, à vous de choisir.
Notez que la redirection de sortie vers un fichier fonctionne comme un charme à la fois sous Linux ET Windows.
Cela me donne envie de souligner que 80% du temps, lorsque je veux utiliser SELECT FROM INFILE ou SELECT INTO OUTFILE, je finis par utiliser autre chose en raison de certaines limitations (ici, l'absence de 'headers options', on un AWS-RDS, les droits manquants, etc.)
Par conséquent, je ne réponds pas exactement à l'op question ... mais il devrait répondre à ses besoins :)
EDIT: et de répondre effectivement à sa question: pas
tant de 07/09/2017, vous ne pouvez pas inclure des en- têtes si vous coller avec la commande SELECT INTO OUTFILE : |
un exemple de mon capteur de nom de table de base de données avec des colonnes (id, heure, 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
J'écrivais mon code en PHP, et j'avais un peu de mal à utiliser les fonctions concat et union, et je n'utilisais pas non plus de variables SQL, de quelque manière que ce soit, je l'ai fait fonctionner, voici mon code:
//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);
Voici un moyen d'obtenir les titres d'en-tête à partir des noms de colonnes de manière dynamique.
/* 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;
Je voudrais ajouter à la réponse fournie par Sangam Belose. Voici son code:
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
Cependant, si vous n'avez pas configuré votre "secure_file_priv"
dans les variables, cela peut ne pas fonctionner. Pour cela, vérifiez le dossier défini sur cette variable en:
SHOW VARIABLES LIKE "secure_file_priv"
La sortie devrait ressembler à ceci:
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)
Vous pouvez modifier cette variable ou modifier la requête pour afficher le fichier dans le chemin par défaut affiché.
MySQL seul ne suffit pas pour faire cela simplement. Vous trouverez ci-dessous un script PHP qui produira des colonnes et des données au format CSV.
Entrez le nom de votre base de données et les tables en haut.
<?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() );
}
?>
Vous aurez besoin de ce répertoire dans lequel vous souhaitez générer la sortie. MySQL doit avoir la capacité d'écrire dans le répertoire.
$path = '/var/lib/mysql/' . $tbl . '.csv';
Vous pouvez modifier les options d'exportation CSV dans la requête:
INTO OUTFILE "' . $path . '"
FIELDS TERMINATED BY ","
ENCLOSED BY "\""
LINES TERMINATED BY "\n"'
À la fin, il y a un appel exécutable à GZip le CSV.
SÉLECTIONNEZ 'ColName1', 'ColName2', 'ColName3' UNION TOUT SELECT ColName1, ColName2, ColName3 DE YourTable INTO OUTFILE 'c: \\ fiche.csv' CHAMPS TERMINÉS PAR ',' FACULTATIVEMENT CLOS PAR '"' LIGNES TERMINÉES PAR '\ n'
ORDER BY
dans l'SELECT
article. La ligne d'en-tête peut être n'importe où dans le fichier généré en fonction de la commande.