Sélectionnez toutes les colonnes sauf une dans MySQL?
365
J'essaie d'utiliser une instruction select pour obtenir toutes les colonnes d'une certaine table MySQL sauf une. Existe-t-il un moyen simple de procéder?
EDIT: Il y a 53 colonnes dans ce tableau (PAS MON DESIGN)
53 colonnes? Je resterais avec SELECT * comme Thomas le suggère dans ce cas ... à moins que cette colonne supplémentaire ne contienne une énorme quantité de données qu'il ne serait pas souhaitable de récupérer ...?
Mike Stone
Sauf une colonne ... Je suppose que vous savez lequel doit être ignoré, donc INFORMATION_SCHEMA.columns est le chemin.
Alfabravo
Découvrez cette réponse, elle fait ce que vous voulez faire!
donL
La colonne Big Data est un vrai problème lorsque les données géographiques sont conservées. Les colonnes peuvent avoir plusieurs mégaoctets. Ils fonctionnent bien dans les clauses where pour trouver des lignes, mais vous ne voulez souvent pas ces données dans les résultats.
Jason
Une utilisation courante pour cela consiste à exclure la colonne ID d'incrémentation automatique. Par exemple, pour sélectionner les données à insérer dans une autre table, qui a son propre ID.
ToolmakerSteve
Réponses:
222
En fait, il existe un moyen, vous devez bien sûr avoir des autorisations pour le faire ...
SET@sql = CONCAT('SELECT ',(SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME),'<columns_to_omit>,','')FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='<table>'AND TABLE_SCHEMA ='<database>'),' FROM <table>');
PREPARE stmt1 FROM@sql;EXECUTE stmt1;
Remplacement <table>, <database> and <columns_to_omit>
mise en garde: les requêtes INFORMATION_SCHEMA ont des performances assez médiocres, alors faites attention à ce type de requête n'est dans le chemin critique pour rien.
C'est bien pire que de simplement spécifier les colonnes, ce qui est une meilleure pratique connue.
HLGEM
3
Cela ne fonctionne pas s'il y a des espaces dans les noms de colonnes. Il devrait être mis à jour pour toujours entourer les noms de guillemets<column_name>
adamF
3
Cela ne fonctionnera pas non plus si la colonne à ignorer est la dernière répertoriée dans la structure du tableau (car le remplacement ne correspondra pas au coma de fin).
Vincent Pazeller
61
Dans les définitions mysql (manuel), cela n'existe pas. Mais si vous avez un très grand nombre de colonnes col1, ... col100, les éléments suivants peuvent être utiles:
M'a donné un message d'erreur à la 3e étape: "Le nombre de colonnes ne correspond pas au nombre de valeurs à la ligne 1". J'ai donc changé l'étape 2 en "UPDATE temp_tb SET id = NULL", puis cela a fonctionné.
oyvey
1
Ok, ça marche. Mais lorsque j'exécute à nouveau cette requête, cela me donne une erreur, que temp_tb existe déjà. Pendant combien de temps le temp_tb est-il en mémoire? Toutes mes excuses si c'est une question stupide. PS a voté pour votre réponse.
Karan
2
@Karan Pour exécuter cette requête à plusieurs reprises, ajoutez une autre commande au début:DROP TABLE IF EXISTS temp_tb;
gregn3
1
@Karan Pour spécifier le moteur de mémoire, utilisez la commande:, CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb); sinon il est enregistré sur le disque par défaut et survit au redémarrage du serveur. ( merci )
gregn3
Excellente réponse. Pour supprimer plusieurs colonnes , reportez-vous à cette réponse .
HAHA! Oui bien sûr. Maintenant, comment construisez-vous la vue pour inclure toutes MAIS une des colonnes. Je pense que vous voyez comment cela soulève la question initiale. En fait, j'ai trouvé ce fil spécifiquement parce que je voulais créer une vue qui excluait certaines colonnes sans être forcé de lister explicitement toutes les colonnes restantes dans la définition de la vue.
La plupart des réponses les mieux notées consistent principalement à trouver des moyens de générer cette requête exacte sans taper à la main
mehtunguh
5
En fait, pour des raisons de maintenance, il est utile d'avoir une requête "tout sauf". Sinon, les listes de champs explicites doivent être mises à jour si de nouveaux champs sont ajoutés ultérieurement.
leiavoia
1
@lev, c'est correct et ils devraient l'être !!! Parce que vous ne savez pas si vous souhaitez avoir des colonnes futures (il peut s'agir de colonnes de métadonnées ou de colonnes qui ne s'appliquent pas à un écran particulier). Vous n'en avez pas; veulent nuire aux performances en retournant plus que ce dont vous avez besoin (ce qui est vrai 100% du temps lorsque vous avez une jointure interne). Je vous suggère de lire pourquoi pourquoi * est un antipattern SQL.
HLGEM
26
L'OP indique qu'il y a> 50 colonnes, ce qui est plutôt peu pratique.
2015
1
@HLGEM Pas vraiment, je voulais sélectionner toutes les colonnes sans maintenir la requête à chaque fois que j'ajoute une nouvelle colonne, sauf une, et cela ne fonctionnerait pas simplement dans mon cas. Mais de toute façon, j'ai appliqué la solution de Sean O pour moi
OverCoder
26
Si vous cherchez à exclure la valeur d'un champ, par exemple pour des problèmes de sécurité / informations sensibles, vous pouvez récupérer cette colonne comme nulle.
Pourquoi? Ça ne marche pas. Si vous avez un salaire de colonne, cette requête se terminera avec les résultats ayant deux colonnes nommées salaire, une pleine de null et une avec les salaires réels.
Myforwik
4
@Myforwik Cette requête ajoute en effet une deuxième salarycolonne. Mais comme il est récupéré après le *, il écrase l'original. Ce n'est pas joli, mais ça marche.
Sean O
68
SQL a toujours autorisé les noms de colonne en double dans un ensemble de résultats. Si vous voulez que cela fonctionne, vous devez l'exécuter avec une application cliente qui ne prend pas en charge les dupes et donne la priorité à la dernière dupe. Le client de ligne de commande officiel prend en charge les dupes. HeidiSQL les prend également en charge. SQL Fiddle ne le fait pas, mais affiche la première dupe, pas la dernière. Pour résumer: cela ne fonctionne pas .
Álvaro González
9
Bien sûr, cela ne fonctionne pas. C'est un excellent exemple de la raison pour laquelle vous devriez tester vos réponses dans mysql lui-même, plutôt que via des bibliothèques qui parlent à mysql.
Myforwik
8
@SeanO, @ Alastair, @ Tout le monde, ne remplace pas. Le serveur renvoie toujours des données sensibles.
Pacerier
22
À ma connaissance, il n'y en a pas. Vous pouvez faire quelque chose comme:
SELECT col1, col2, col3, col4 FROM tbl
et choisissez manuellement les colonnes souhaitées. Cependant, si vous voulez beaucoup de colonnes, vous pouvez simplement faire un:
SELECT*FROM tbl
et ignorez simplement ce que vous ne voulez pas.
Dans votre cas particulier, je suggère:
SELECT*FROM tbl
sauf si vous ne voulez que quelques colonnes. Si vous ne voulez que quatre colonnes, alors:
SELECT col3, col6, col45, col 52FROM tbl
serait bien, mais si vous voulez 50 colonnes, alors tout code qui rend la requête deviendrait (trop?) difficile à lire.
Sélectionnez * est toujours un mauvais choix. Je ne le recommande pas. Découvrez pourquoi il s'agit d'un anti-modèle SQl.
HLGEM
18
En essayant les solutions de @Mahomedalid et @Junaid, j'ai trouvé un problème. Alors j'ai pensé à le partager. Si le nom de la colonne contient des espaces ou des tirets comme l'archivage, la requête échoue. La solution de contournement simple consiste à utiliser la barre oblique inverse autour des noms de colonne. La requête modifiée est ci-dessous
SET@SQL = CONCAT('SELECT ',(SELECT GROUP_CONCAT(CONCAT("`", COLUMN_NAME,"`"))FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='users'AND COLUMN_NAME NOTIN('id')),' FROM users');
PREPARE stmt1 FROM@SQL;EXECUTE stmt1;
Si la colonne que vous ne vouliez pas sélectionner contenait une énorme quantité de données et que vous ne vouliez pas l'inclure en raison de problèmes de vitesse et que vous sélectionnez souvent les autres colonnes, je vous suggère de créer une nouvelle table avec le seul champ que vous ne sélectionnez généralement pas avec une clé de la table d'origine et supprimez le champ de la table d'origine. Rejoignez les tables lorsque ce champ supplémentaire est réellement requis.
Mon principal problème est le nombre de colonnes que j'obtiens en joignant des tables. Bien que ce ne soit pas la réponse à votre question (comment sélectionner toutes les colonnes, sauf certaines, d' une même table), je pense qu'il convient de mentionner que vous pouvez spécifier d'obtenir toutes les colonnes d'une table particulière, au lieu de simplement spécifier .table.
Voici un exemple de la façon dont cela pourrait être très utile:
sélectionnez les utilisateurs. *, phone.meta_value comme téléphone, zipcode.meta_value comme zipcode
des utilisateurs
joindre à gauche user_meta comme téléphone
on ((users.user_id = phone.user_id) AND (phone.meta_key = 'phone'))
rejoindre à gauche user_meta comme code postal
on ((users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'zipcode')))
Le résultat est toutes les colonnes de la table des utilisateurs et deux colonnes supplémentaires qui ont été jointes à partir de la méta-table.
merci, j'ai besoin de sélectionner toutes les colonnes de la première table et un seul champ de la deuxième table en joignant et votre réponse m'a aidé.
mohammad falahat
5
J'ai aimé la réponse de d' @Mahomedalidailleurs ce fait informé dans le commentaire de @Bill Karwin. Le problème possible soulevé par @Jan Koritakest vrai, j'ai fait face à cela, mais j'ai trouvé une astuce pour cela et je veux juste le partager ici pour toute personne confrontée au problème.
nous pouvons remplacer la fonction REPLACE par la clause where dans la sous-requête de l'instruction Prepared comme ceci:
Utilisation de mon nom de table et de colonne
SET@SQL = CONCAT('SELECT ',(SELECT GROUP_CONCAT(COLUMN_NAME)FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='users'AND COLUMN_NAME NOTIN('id')),' FROM users');
PREPARE stmt1 FROM@SQL;EXECUTE stmt1;
Donc, cela va exclure uniquement le champ idmais pascompany_id
Il agit comme un contrat avec le code et lorsque vous regardez la requête, vous savez exactement quelles données vous pouvez en extraire sans regarder le schéma de la table.
mbillard
6
@kodecraft: C'est une bonne pratique pour la même raison que c'est toujours une bonne pratique de retourner le même type à partir d'une fonction (même si vous travaillez dans une langue où cela n'est pas appliqué). Fondamentalement, juste le principe de la moindre surprise.
Daniel Pryden
4
Fais juste
SELECT*FROMtableWHERE whatever
Déposez ensuite la colonne dans votre langage de programmation préféré: php
À moins que la colonne que vous souhaitez exclure soit un énorme BLOB ou quelque chose.
Bill Karwin
1
C'est mauvais si vous essayez d'éviter les données gaspillées.
Kristopher Ives
1 colonne sur 53 ne devrait faire aucune différence. Si c'est le cas, c'est probablement une mauvaise conception.
Petr Peller
1
SElect * est un antipattern SQL et ne doit jamais être utilisé dans le code de production.
HLGEM
1
Je ne suis pas d'accord que SELECT * est une sorte d'anti-modèle qui ne devrait "jamais" être utilisé dans le code de production. Il est beaucoup plus clair que vous avez récupéré toutes vos colonnes - par rapport au croisement d'une longue liste de colonnes qui peuvent, ou non, être en fait tous les champs. C'est aussi, de toute évidence, plus rapide à coder, de loin. Et il existe de très nombreux cas où les champs de la table correspondront exactement aux champs d'une vue ou d'un formulaire.
Geoff Kendall
4
Je suis d'accord avec la solution "simple" consistant à répertorier toutes les colonnes, mais cela peut être fastidieux et les fautes de frappe peuvent entraîner beaucoup de perte de temps. J'utilise une fonction "getTableColumns" pour récupérer les noms de mes colonnes pouvant être collés dans une requête. Ensuite, tout ce que je dois faire est de supprimer ceux dont je ne veux pas.
CREATEFUNCTION`getTableColumns`(tablename varchar(100))
RETURNS varchar(5000) CHARSET latin1
BEGINDECLARE done INT DEFAULT0;DECLARE res VARCHAR(5000)DEFAULT"";DECLARE col VARCHAR(200);DECLARE cur1 CURSORFORselect COLUMN_NAME from information_schema.columns
where TABLE_NAME=@tableAND TABLE_SCHEMA="yourdatabase"ORDERBY ORDINAL_POSITION;DECLARECONTINUE HANDLER FORNOT FOUND SET done =1;OPEN cur1;
REPEAT
FETCH cur1 INTO col;IFNOT done THENset res = CONCAT(res,IF(LENGTH(res)>0,",",""),col);ENDIF;
UNTIL done END REPEAT;CLOSE cur1;RETURN res;
Votre résultat renvoie une chaîne séparée par des virgules, par exemple ...
Ce sera terriblement lent pour toute table de taille moyenne.
Joel
3
Je suis d'accord qu'il ne suffit pas Select *, si celui dont vous n'avez pas besoin, comme mentionné ailleurs, est un BLOB, vous ne voulez pas que cette surcharge s'introduise.
Je créerais une vue avec les données requises, alors vous pouvez Select *dans le confort - si le logiciel de base de données les prend en charge. Sinon, mettez les énormes données dans un autre tableau.
Au début, je pensais que vous pouviez utiliser des expressions régulières, mais comme j'ai lu les documents MYSQL, il semble que vous ne puissiez pas. Si j'étais vous, j'utiliserais un autre langage (tel que PHP) pour générer une liste de colonnes que vous souhaitez obtenir, le stocker sous forme de chaîne, puis l'utiliser pour générer le SQL.
Donc, comment cela fonctionne, c'est que vous entrez dans la table, puis une colonne que vous ne voulez pas ou comme dans un tableau: tableau ("id", "nom", "quelle que soit la colonne")
Donc, dans select, vous pouvez l'utiliser comme ceci:
mysql_query("SELECT ".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table");
ou
mysql_query("SELECT ".$db->getColsExcept('table','bigtextcolumn')." FROM table");
Je suis d'accord avec la réponse de @ Mahomedalid, mais je ne voulais pas faire quelque chose comme une déclaration préparée et je ne voulais pas taper tous les champs, donc ce que j'avais était une solution idiote.
Allez dans le tableau dans phpmyadmin-> sql-> sélectionnez, il vide la requête: copiez, remplacez et c'est fait! :)
Bien que je sois d'accord avec la réponse de Thomas (+1;)), je voudrais ajouter la mise en garde que je suppose que la colonne que vous ne voulez pas contient presque aucune donnée. S'il contient d'énormes quantités de texte, des objets XML ou des objets binaires binaires, prenez le temps de sélectionner chaque colonne individuellement. Votre performance en souffrira autrement. À votre santé!
La réponse publiée par Mahomedalid a un petit problème:
Le code de fonction de remplacement interne remplaçait "<columns_to_delete>, " par "", ce remplacement a un problème si le champ à remplacer est le dernier de la chaîne de concaténation car le dernier n'a pas la virgule char "," et n'est pas supprimé de la chaîne.
Ma proposition:
SET@sql = CONCAT('SELECT ',(SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME),'<columns_to_delete>','\'FIELD_REMOVED\'')FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME ='<table>'AND TABLE_SCHEMA ='<database>'),' FROM <table>');
Remplacement <table>,<database> et `
La colonne supprimée est remplacée par la chaîne "FIELD_REMOVED" dans mon cas, cela fonctionne parce que j'essayais de sauvegarder la mémoire. (Le champ que je supprimais est un BLOB d'environ 1 Mo)
Sur la base de la réponse de @Mahomedalid, j'ai apporté quelques améliorations pour prendre en charge "sélectionner toutes les colonnes sauf certaines dans mysql"
SET@database='database_name';SET@tablename ='table_name';SET@cols2delete ='col1,col2,col3';SET@sql = CONCAT('SELECT ',(SELECT GROUP_CONCAT(IF(FIND_IN_SET(COLUMN_NAME,@cols2delete),NULL, COLUMN_NAME ))FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =@tablename AND TABLE_SCHEMA =@database),' FROM ',@tablename);SELECT@sql;
Si vous avez beaucoup de colonnes, utilisez ce SQL pour changer group_concat_max_len
Peut-être ai-je une solution à l' écart signalé par Jan Koritak
SELECT CONCAT('SELECT ',(SELECT GROUP_CONCAT(t.col)FROM(SELECTCASEWHEN COLUMN_NAME ='eid'THENNULLELSE COLUMN_NAME
ENDAS col
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME ='employee'AND TABLE_SCHEMA ='test') t
WHERE t.col ISNOTNULL),' FROM employee');
Table :
SELECT table_name,column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME ='employee'AND TABLE_SCHEMA ='test'
================================
table_name column_name
employee eid
employee name_eid
employee sal
Vous pouvez utiliser SQL pour générer du SQL si vous le souhaitez et évaluer le SQL qu'il produit. Il s'agit d'une solution générale car elle extrait les noms de colonne du schéma d'informations. Voici un exemple de la ligne de commande Unix.
Substitution
MYSQL avec votre commande mysql
TABLE avec le nom de la table
EXCLUDEDFIELD avec le nom de champ exclu
echo $(echo 'select concat("select ", group_concat(column_name) , " from TABLE") from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"'| MYSQL | tail -n 1)| MYSQL
Vous n'aurez vraiment besoin d'extraire les noms de colonne de cette façon qu'une seule fois pour construire la liste des colonnes excluant cette colonne, puis utilisez simplement la requête que vous avez construite.
Donc quelque chose comme:
column_list=$(echo 'select group_concat(column_name) from information_schema.columns where table_name="TABLE" and column_name != "EXCLUDEDFIELD" group by "t"'| MYSQL | tail -n 1)
Vous pouvez maintenant réutiliser la $column_listchaîne dans les requêtes que vous construisez.
Je voudrais ajouter un autre point de vue afin de résoudre ce problème, surtout si vous avez un petit nombre de colonnes à supprimer.
Vous pouvez utiliser un outil de base de données comme MySQL Workbench afin de générer l'instruction select pour vous, il vous suffit donc de supprimer manuellement ces colonnes pour l'instruction générée et de la copier dans votre script SQL.
Dans MySQL Workbench, la façon de le générer est:
Cliquez avec le bouton droit sur le tableau -> envoyer à l'Éditeur SQL -> Sélectionner toute la déclaration.
Il échoue lorsque les noms de table ou de colonne nécessitent des raccourcis
Il échoue si la colonne que vous souhaitez omettre est la dernière de la liste
Cela nécessite de répertorier le nom de la table deux fois (une pour la sélection et une autre pour le texte de la requête), ce qui est redondant et inutile
Il peut potentiellement retourner des noms de colonne dans le mauvais ordre
Tous ces problèmes peuvent être surmontés en incluant simplement des backticks dans le SEPARATORfor your GROUP_CONCATet en utilisant une WHEREcondition à la place de REPLACE(). Pour mes besoins (et j'imagine beaucoup d'autres), je voulais que les noms des colonnes soient retournés dans le même ordre qu'ils apparaissent dans le tableau lui-même. Pour ce faire, nous utilisons ici une ORDER BYclause explicite à l' intérieur de la GROUP_CONCAT()fonction:
Je suis assez tard pour trouver une réponse à cela, c'est comme ça que je l'ai toujours fait et franchement, c'est 100 fois mieux et plus net que la meilleure réponse, j'espère seulement que quelqu'un le verra. Et trouvez-le utile
//create an array, we will call it here.$here = array();//create an SQL query inorderto get allof the column names
$SQL ="SHOW COLUMNS FROM Table";//put allof the column names in the array
foreach($conn->query($SQL)as$row){$here[]=$row[0];}//now search through the array containing the column names for the name of the column,in this case i used the common ID field as an example
$key= array_search('ID',$here);//now delete the entry
unset($here[$key]);
C'est peut-être bien, mais cela ne répond pas à la question: il n'a pas posé de questions sur php, et vous ne donnez pas une instruction select ou un résultat de ce qu'il veut, mais seulement un tableau php contenant les colonnes qu'il veut.
gou1
2
-1. Ce n'est pas du code SQL, et il n'y a aucune SELECTdéclaration ici - le mot ne se produit même pas une seule fois.
Frungi
Cela n'est plus net que dans la mesure où (a) vous êtes plus à l'aise avec PHP que SQL, ou (b) vous aimez diffuser votre code sur plusieurs lignes pour plus de lisibilité. Je concéderais le point (b). Votre approche serait également moins performante, bien que la différence soit mineure dans de nombreux cas d'utilisation. Voir également d'autres commentaires sur votre question. Cela ne vaut pas la peine d'être crié, alors suggérez de supprimer votre commentaire inapproprié de la question d'origine.
mc0e
-5
Select * est un antipattern SQL. Il ne doit pas être utilisé dans le code de production pour de nombreuses raisons, notamment:
Le traitement prend un tout petit peu plus de temps. Lorsque les choses sont exécutées des millions de fois, ces minuscules morceaux peuvent être importants. Une base de données lente où la lenteur est causée par ce type de codage bâclé est le type le plus difficile à régler.
Cela signifie que vous envoyez probablement plus de données que nécessaire, ce qui provoque des goulots d'étranglement du serveur et du réseau. Si vous avez une jointure interne, les chances d'envoyer plus de données que vous n'en avez besoin sont de 100%.
Cela provoque des problèmes de maintenance, en particulier lorsque vous avez ajouté de nouvelles colonnes que vous ne souhaitez pas voir partout. De plus, si vous avez une nouvelle colonne, vous devrez peut-être faire quelque chose à l'interface pour déterminer quoi faire avec cette colonne.
Il peut casser des vues (je sais que cela est vrai dans le serveur SQl, cela peut ou peut ne pas être vrai dans mysql).
Si quelqu'un est assez idiot pour reconstruire les tables avec les colonnes dans un ordre différent (ce que vous ne devriez pas faire mais cela arrive tout le temps), toutes sortes de codes peuvent casser. Surtout codez pour un insert par exemple où soudainement vous mettez la ville dans le champ address_3 parce que sans préciser, la base de données ne peut aller que dans l'ordre des colonnes. C'est déjà assez mauvais lorsque les types de données changent, mais pire quand les colonnes échangées ont le même type de données, car vous pouvez parfois insérer des données incorrectes qui sont un gâchis à nettoyer. Vous devez vous soucier de l'intégrité des données.
S'il est utilisé dans une insertion, il cassera l'insertion si une nouvelle colonne est ajoutée dans une table mais pas dans l'autre.
Cela pourrait casser les déclencheurs. Les problèmes de déclenchement peuvent être difficiles à diagnostiquer.
Ajoutez tout cela au temps qu'il faut pour ajouter les noms des colonnes (diable, vous pouvez même avoir une interface qui vous permet de faire glisser les noms des colonnes (je sais que je le fais dans SQL Server, je parierais qu'il existe un moyen de faites ceci est un outil que vous utilisez pour écrire des requêtes mysql.) Voyons, "Je peux causer des problèmes de maintenance, je peux causer des problèmes de performances et je peux causer des problèmes d'intégrité des données, mais bon j'ai économisé cinq minutes de temps de développement." dans les colonnes spécifiques que vous souhaitez.
Réponses:
En fait, il existe un moyen, vous devez bien sûr avoir des autorisations pour le faire ...
Remplacement
<table>, <database> and <columns_to_omit>
la source
<column_name>
Dans les définitions mysql (manuel), cela n'existe pas. Mais si vous avez un très grand nombre de colonnes
col1
, ...col100
, les éléments suivants peuvent être utiles:la source
DROP TABLE IF EXISTS temp_tb;
CREATE TEMPORARY TABLE temp_tb ENGINE=MEMORY (SELECT * FROM orig_tb);
sinon il est enregistré sur le disque par défaut et survit au redémarrage du serveur. ( merci )Une vue fonctionnerait-elle mieux dans ce cas?
la source
Tu peux faire:
sans obtenir column3, mais peut-être que vous cherchiez une solution plus générale?
la source
Si vous cherchez à exclure la valeur d'un champ, par exemple pour des problèmes de sécurité / informations sensibles, vous pouvez récupérer cette colonne comme nulle.
par exemple
la source
salary
colonne. Mais comme il est récupéré après le *, il écrase l'original. Ce n'est pas joli, mais ça marche.À ma connaissance, il n'y en a pas. Vous pouvez faire quelque chose comme:
et choisissez manuellement les colonnes souhaitées. Cependant, si vous voulez beaucoup de colonnes, vous pouvez simplement faire un:
et ignorez simplement ce que vous ne voulez pas.
Dans votre cas particulier, je suggère:
sauf si vous ne voulez que quelques colonnes. Si vous ne voulez que quatre colonnes, alors:
serait bien, mais si vous voulez 50 colonnes, alors tout code qui rend la requête deviendrait (trop?) difficile à lire.
la source
En essayant les solutions de @Mahomedalid et @Junaid, j'ai trouvé un problème. Alors j'ai pensé à le partager. Si le nom de la colonne contient des espaces ou des tirets comme l'archivage, la requête échoue. La solution de contournement simple consiste à utiliser la barre oblique inverse autour des noms de colonne. La requête modifiée est ci-dessous
la source
Si la colonne que vous ne vouliez pas sélectionner contenait une énorme quantité de données et que vous ne vouliez pas l'inclure en raison de problèmes de vitesse et que vous sélectionnez souvent les autres colonnes, je vous suggère de créer une nouvelle table avec le seul champ que vous ne sélectionnez généralement pas avec une clé de la table d'origine et supprimez le champ de la table d'origine. Rejoignez les tables lorsque ce champ supplémentaire est réellement requis.
la source
Vous pouvez utiliser DESCRIBE my_table et en utiliser les résultats pour générer dynamiquement l'instruction SELECT.
la source
Mon principal problème est le nombre de colonnes que j'obtiens en joignant des tables. Bien que ce ne soit pas la réponse à votre question (comment sélectionner toutes les colonnes, sauf certaines, d' une même table), je pense qu'il convient de mentionner que vous pouvez spécifier d'obtenir toutes les colonnes d'une table particulière, au lieu de simplement spécifier .
table.
Voici un exemple de la façon dont cela pourrait être très utile:
Le résultat est toutes les colonnes de la table des utilisateurs et deux colonnes supplémentaires qui ont été jointes à partir de la méta-table.
la source
J'ai aimé la réponse de d'
@Mahomedalid
ailleurs ce fait informé dans le commentaire de@Bill Karwin
. Le problème possible soulevé par@Jan Koritak
est vrai, j'ai fait face à cela, mais j'ai trouvé une astuce pour cela et je veux juste le partager ici pour toute personne confrontée au problème.nous pouvons remplacer la fonction REPLACE par la clause where dans la sous-requête de l'instruction Prepared comme ceci:
Utilisation de mon nom de table et de colonne
Donc, cela va exclure uniquement le champ
id
mais pascompany_id
la source
Il est recommandé de spécifier les colonnes que vous interrogez même si vous interrogez toutes les colonnes.
Je vous suggère donc d'écrire le nom de chaque colonne dans la déclaration (à l'exclusion de celle que vous ne voulez pas).
la source
Fais juste
Déposez ensuite la colonne dans votre langage de programmation préféré: php
la source
Je suis d'accord avec la solution "simple" consistant à répertorier toutes les colonnes, mais cela peut être fastidieux et les fautes de frappe peuvent entraîner beaucoup de perte de temps. J'utilise une fonction "getTableColumns" pour récupérer les noms de mes colonnes pouvant être collés dans une requête. Ensuite, tout ce que je dois faire est de supprimer ceux dont je ne veux pas.
Votre résultat renvoie une chaîne séparée par des virgules, par exemple ...
la source
Oui, bien qu'il puisse y avoir des E / S élevées selon la table, voici une solution de contournement que j'ai trouvée pour cela.
la source
Je suis d'accord qu'il ne suffit pas
Select *
, si celui dont vous n'avez pas besoin, comme mentionné ailleurs, est un BLOB, vous ne voulez pas que cette surcharge s'introduise.Je créerais une vue avec les données requises, alors vous pouvez
Select *
dans le confort - si le logiciel de base de données les prend en charge. Sinon, mettez les énormes données dans un autre tableau.la source
Au début, je pensais que vous pouviez utiliser des expressions régulières, mais comme j'ai lu les documents MYSQL, il semble que vous ne puissiez pas. Si j'étais vous, j'utiliserais un autre langage (tel que PHP) pour générer une liste de colonnes que vous souhaitez obtenir, le stocker sous forme de chaîne, puis l'utiliser pour générer le SQL.
la source
Je le voulais aussi, j'ai donc créé une fonction à la place.
Donc, comment cela fonctionne, c'est que vous entrez dans la table, puis une colonne que vous ne voulez pas ou comme dans un tableau: tableau ("id", "nom", "quelle que soit la colonne")
Donc, dans select, vous pouvez l'utiliser comme ceci:
ou
la source
Je suis d'accord avec la réponse de @ Mahomedalid, mais je ne voulais pas faire quelque chose comme une déclaration préparée et je ne voulais pas taper tous les champs, donc ce que j'avais était une solution idiote.
Allez dans le tableau dans phpmyadmin-> sql-> sélectionnez, il vide la requête: copiez, remplacez et c'est fait! :)
la source
Bien que je sois d'accord avec la réponse de Thomas (+1;)), je voudrais ajouter la mise en garde que je suppose que la colonne que vous ne voulez pas contient presque aucune donnée. S'il contient d'énormes quantités de texte, des objets XML ou des objets binaires binaires, prenez le temps de sélectionner chaque colonne individuellement. Votre performance en souffrira autrement. À votre santé!
la source
La réponse publiée par Mahomedalid a un petit problème:
Le code de fonction de remplacement interne remplaçait "
<columns_to_delete>,
" par "", ce remplacement a un problème si le champ à remplacer est le dernier de la chaîne de concaténation car le dernier n'a pas la virgule char "," et n'est pas supprimé de la chaîne.Ma proposition:
Remplacement
<table>
,<database>
et `La colonne supprimée est remplacée par la chaîne "FIELD_REMOVED" dans mon cas, cela fonctionne parce que j'essayais de sauvegarder la mémoire. (Le champ que je supprimais est un BLOB d'environ 1 Mo)
la source
Sur la base de la réponse de @Mahomedalid, j'ai apporté quelques améliorations pour prendre en charge "sélectionner toutes les colonnes sauf certaines dans mysql"
Si vous avez beaucoup de colonnes, utilisez ce SQL pour changer group_concat_max_len
la source
Peut-être ai-je une solution à l' écart signalé par Jan Koritak
Table :
================================
================================
Résultat de la requête:
la source
Si c'est toujours la même colonne, vous pouvez créer une vue qui ne la contient pas.
Sinon, non, je ne pense pas.
la source
Vous pouvez utiliser SQL pour générer du SQL si vous le souhaitez et évaluer le SQL qu'il produit. Il s'agit d'une solution générale car elle extrait les noms de colonne du schéma d'informations. Voici un exemple de la ligne de commande Unix.
Substitution
Vous n'aurez vraiment besoin d'extraire les noms de colonne de cette façon qu'une seule fois pour construire la liste des colonnes excluant cette colonne, puis utilisez simplement la requête que vous avez construite.
Donc quelque chose comme:
Vous pouvez maintenant réutiliser la
$column_list
chaîne dans les requêtes que vous construisez.la source
Je voudrais ajouter un autre point de vue afin de résoudre ce problème, surtout si vous avez un petit nombre de colonnes à supprimer.
Vous pouvez utiliser un outil de base de données comme MySQL Workbench afin de générer l'instruction select pour vous, il vous suffit donc de supprimer manuellement ces colonnes pour l'instruction générée et de la copier dans votre script SQL.
Dans MySQL Workbench, la façon de le générer est:
Cliquez avec le bouton droit sur le tableau -> envoyer à l'Éditeur SQL -> Sélectionner toute la déclaration.
la source
La réponse acceptée présente plusieurs lacunes.
Tous ces problèmes peuvent être surmontés en incluant simplement des backticks dans le
SEPARATOR
for yourGROUP_CONCAT
et en utilisant uneWHERE
condition à la place deREPLACE()
. Pour mes besoins (et j'imagine beaucoup d'autres), je voulais que les noms des colonnes soient retournés dans le même ordre qu'ils apparaissent dans le tableau lui-même. Pour ce faire, nous utilisons ici uneORDER BY
clause explicite à l' intérieur de laGROUP_CONCAT()
fonction:la source
J'ai une suggestion mais pas une solution. Si certaines de vos colonnes ont des ensembles de données plus volumineux, vous devriez essayer de suivre
la source
Je suis assez tard pour trouver une réponse à cela, c'est comme ça que je l'ai toujours fait et franchement, c'est 100 fois mieux et plus net que la meilleure réponse, j'espère seulement que quelqu'un le verra. Et trouvez-le utile
la source
SELECT
déclaration ici - le mot ne se produit même pas une seule fois.Select * est un antipattern SQL. Il ne doit pas être utilisé dans le code de production pour de nombreuses raisons, notamment:
Le traitement prend un tout petit peu plus de temps. Lorsque les choses sont exécutées des millions de fois, ces minuscules morceaux peuvent être importants. Une base de données lente où la lenteur est causée par ce type de codage bâclé est le type le plus difficile à régler.
Cela signifie que vous envoyez probablement plus de données que nécessaire, ce qui provoque des goulots d'étranglement du serveur et du réseau. Si vous avez une jointure interne, les chances d'envoyer plus de données que vous n'en avez besoin sont de 100%.
Cela provoque des problèmes de maintenance, en particulier lorsque vous avez ajouté de nouvelles colonnes que vous ne souhaitez pas voir partout. De plus, si vous avez une nouvelle colonne, vous devrez peut-être faire quelque chose à l'interface pour déterminer quoi faire avec cette colonne.
Il peut casser des vues (je sais que cela est vrai dans le serveur SQl, cela peut ou peut ne pas être vrai dans mysql).
Si quelqu'un est assez idiot pour reconstruire les tables avec les colonnes dans un ordre différent (ce que vous ne devriez pas faire mais cela arrive tout le temps), toutes sortes de codes peuvent casser. Surtout codez pour un insert par exemple où soudainement vous mettez la ville dans le champ address_3 parce que sans préciser, la base de données ne peut aller que dans l'ordre des colonnes. C'est déjà assez mauvais lorsque les types de données changent, mais pire quand les colonnes échangées ont le même type de données, car vous pouvez parfois insérer des données incorrectes qui sont un gâchis à nettoyer. Vous devez vous soucier de l'intégrité des données.
S'il est utilisé dans une insertion, il cassera l'insertion si une nouvelle colonne est ajoutée dans une table mais pas dans l'autre.
Cela pourrait casser les déclencheurs. Les problèmes de déclenchement peuvent être difficiles à diagnostiquer.
Ajoutez tout cela au temps qu'il faut pour ajouter les noms des colonnes (diable, vous pouvez même avoir une interface qui vous permet de faire glisser les noms des colonnes (je sais que je le fais dans SQL Server, je parierais qu'il existe un moyen de faites ceci est un outil que vous utilisez pour écrire des requêtes mysql.) Voyons, "Je peux causer des problèmes de maintenance, je peux causer des problèmes de performances et je peux causer des problèmes d'intégrité des données, mais bon j'ai économisé cinq minutes de temps de développement." dans les colonnes spécifiques que vous souhaitez.
Je vous suggère également de lire ce livre: http://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers-ebook/dp/B00A376BB2/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1389896688&sr=1- 1 & mots-clés = sql + antipatterns
la source