Sélectionnez Toutes les colonnes sauf une dans MySQL?

J'essaie d'utiliser une instruction select pour obtenir toutes les colonnes d'une certaine table MySQL sauf une. Est-il un moyen simple de faire cela?

EDIT: il y a 53 colonnes dans ce tableau (pas mon DESIGN)

309
demandé sur Tom Grochowicz 2008-08-12 22:45:55

28 réponses

En fait, il y a un moyen, vous devez avoir des autorisations bien sûr 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 de <table>, <database> and <columns_to_omit>

195
répondu Mahomedalid 2013-10-01 08:07:54

Une vue fonctionnerait-elle mieux dans ce cas?

CREATE VIEW vwTable
as  
SELECT  
    col1  
    , col2  
    , col3  
    , col..  
    , col53  
FROM table
39
répondu Brian Childress 2008-08-12 19:45:01

Dans les définitions mysql (manual), il n'y a pas une telle chose. Mais si vous avez un très grand nombre de colonnes col1,..., col100, ce qui suit peut être utile:

mysql> CREATE TEMPORARY TABLE temp_tb SELECT * FROM orig_tb;
mysql> ALTER TABLE temp_tb DROP col_x;
mysql> SELECT * FROM temp_tb;
39
répondu ghionoiu 2012-02-18 00:56:57

Vous pouvez faire:

SELECT column1, column2, column4 FROM table WHERE whatever

Sans obtenir column3, bien que vous cherchiez peut-être une solution plus générale?

31
répondu Mike Stone 2008-08-12 18:48:04

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 en tant que null.

Par exemple

SELECT *, NULL AS salary FROM users
29
répondu Sean O 2013-06-13 17:24:06

Au meilleur de 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 que vous voulez. Cependant, si vous voulez beaucoup de colonnes, alors vous voudrez peut-être juste 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 voulez seulement quelques colonnes. Si vous voulez seulement quatre colonnes, alors:

SELECT col3, col6, col45, col 52 FROM tbl

Serait bien, mais si vous voulez 50 colonnes, alors tout code qui fait le requête deviendrait (trop? difficile à lire.

23
répondu Thomas Owens 2012-03-30 14:08:14

En essayant les solutions par @ Mahomedalid et @ Junaid j'ai trouvé un problème. Alors pensé à le partager. Si le nom de la colonne a des espaces ou des tirets comme l'enregistrement, la requête échouera. La solution de contournement simple consiste à utiliser backtick autour des noms de colonnes. 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 NOT IN ('id')), ' FROM users');
PREPARE stmt1 FROM @SQL;
EXECUTE stmt1;
13
répondu Suraj 2013-07-18 09:01:56

Si la colonne que vous ne vouliez pas sélectionner contenait une quantité massive 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 champ que vous ne sélectionnez pas habituellement avec une clé de la table d'origine et de supprimer le champ de la table d'origine. Joindre les tables lorsque ce champ supplémentaire est nécessaire.

12
répondu Stacey Richards 2008-08-12 18:56:35

Vous pouvez utiliser DESCRIBE my_table et en utiliser les résultats pour générer dynamiquement L'instruction SELECT.

9
répondu jammycakes 2008-08-12 19:01:14

Mon principal problème est les nombreuses colonnes que je reçois en joignant des tables. Bien que ce ne soit pas la réponse à votre question (Comment sélectionner toutes les colonnes sauf Certaines de une table), je pense qu'il vaut la peine de mentionner que vous pouvez spécifier table. pour obtenir toutes les colonnes d'une table particulière, au lieu de simplement spécifier .

Voici un exemple de comment cela pourrait être très utile:

select users.*, phone.meta_value as phone, zipcode.meta_value as zipcode

from users

left join user_meta as phone
on ( (users.user_id = phone.user_id) AND (phone.meta_key = 'phone') )

left join user_meta as zipcode
on ( (users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'zipcode') )

Le résultat est toutes les colonnes de la table users, et deux colonnes supplémentaires qui étaient joint à partir de la table meta.

6
répondu cwd 2011-07-08 12:26:11

J'ai aimé la réponse de @Mahomedalid en plus de ce fait informé dans le commentaire de @Bill Karwin. Le problème possible soulevé par @Jan Koritak est vrai que j'ai fait face à cela, mais j'ai trouvé un truc pour cela et je veux juste le partager ici pour tous ceux qui font face au problème.

Nous pouvons remplacer la fonction REPLACE par la clause where dans la sous-requête de L'instruction préparée comme ceci:

En utilisant 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 NOT IN ('id')), ' FROM users');
PREPARE stmt1 FROM @SQL;
EXECUTE stmt1;

Donc, cela va exclure que le champ id, mais pas company_id

Espoir cela aidera tous ceux qui recherchent une solution.

Cordialement

5
répondu Junaid 2012-05-15 09:56:16

, Il est recommandé de spécifier les colonnes que vous interrogez, même si vous interrogez toutes les colonnes.

Donc, je vous suggère d'écrire le nom de chaque colonne dans l'instruction (à l'exclusion de celle que vous ne voulez pas).

SELECT
    col1
    , col2
    , col3
    , col..
    , col53

FROM table
4
répondu mbillard 2008-08-12 19:24:01

Je suis d'accord avec la solution "simple" de lister toutes les colonnes, mais cela peut être lourd, et les fautes de frappe peuvent causer beaucoup de temps perdu. J'utilise une fonction "getTableColumns" pour récupérer les noms de mes colonnes appropriées pour coller dans une requête. Ensuite, tout ce que je dois faire est de supprimer ceux que je ne veux pas.

CREATE FUNCTION `getTableColumns`(tablename varchar(100)) 
          RETURNS varchar(5000) CHARSET latin1
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE res  VARCHAR(5000) DEFAULT "";

  DECLARE col  VARCHAR(200);
  DECLARE cur1 CURSOR FOR 
    select COLUMN_NAME from information_schema.columns 
    where TABLE_NAME=@table AND TABLE_SCHEMA="yourdatabase" ORDER BY ORDINAL_POSITION;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  OPEN cur1;
  REPEAT
       FETCH cur1 INTO col;
       IF NOT done THEN 
          set res = CONCAT(res,IF(LENGTH(res)>0,",",""),col);
       END IF;
    UNTIL done END REPEAT;
  CLOSE cur1;
  RETURN res;

Votre résultat renvoie une chaîne délimitée par des virgules, par exemple...

Col1,col2,col3,col4,...col53

4
répondu David Poor 2011-01-07 03:20:13

Je suis d'accord qu'il ne suffit pas de Select *, si celui dont vous n'avez pas besoin, comme mentionné ailleurs, est un BLOB, vous ne voulez pas avoir ce fluage aérien.

Je créerais une vue avec les données requises, alors vous pouvez Select * dans comfort-si le logiciel de base de données les supporte. Sinon, mettez les énormes données dans une autre table.

3
répondu nlucaroni 2008-08-12 19:12:23

Faites juste

SELECT * FROM table WHERE whatever

Ensuite, déposez la colonne dans votre langage de programmation préféré: php

while (($data = mysql_fetch_array($result, MYSQL_ASSOC)) !== FALSE) {
   unset($data["id"]);
   foreach ($data as $k => $v) { 
      echo"$v,";
   }      
}
3
répondu Soth 2010-01-07 10:02:01

Je le voulais aussi alors j'ai créé une fonction à la place.

public function getColsExcept($table,$remove){
    $res =mysql_query("SHOW COLUMNS FROM $table");

    while($arr = mysql_fetch_assoc($res)){
        $cols[] = $arr['Field'];
    }
    if(is_array($remove)){
        $newCols = array_diff($cols,$remove);
        return "`".implode("`,`",$newCols)."`";
    }else{
        $length = count($cols);
        for($i=0;$i<$length;$i++){
            if($cols[$i] == $remove)
                unset($cols[$i]);
        }
        return "`".implode("`,`",$cols)."`";
    }
}

Alors, comment cela fonctionne est que vous entrer dans le tableau, puis une colonne, vous ne voulez pas, ou comme dans un tableau: array("id","nom","whatevercolumn")

, de Sorte à sélectionner, 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");
3
répondu Kilise 2013-03-22 13:37:06

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 pratiquement aucune donnée. Si elle contient d'énormes quantités de texte, xml ou binaire gouttes, puis prendre le temps de sélectionner chaque colonne individuellement. Votre performance en souffrira autrement. À votre santé!

2
répondu OJ. 2008-08-12 20:43:21

Oui, bien qu'il puisse être élevé e / s en fonction de la table voici une solution de contournement que j'ai trouvée pour cela.

Select *
into #temp
from table

alter table #temp drop column column_name

Select *
from #temp
2
répondu Nathan A 2010-02-24 01:21:10

La réponse Postée par Mahomedalid a un petit problème:

À l'intérieur du code de fonction replace remplaçait "<columns_to_delete>, " par "", ce remplacement a un problème si le champ à remplacer est le dernier dans la chaîne concat en raison du 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 coffre-fort de la mémoire. (Le champ que je supprimais est un BLOB d'environ 1 Mo)

2
répondu neurotico79 2011-11-07 13:54:26

Basé sur la réponse @Mahomedalid, j'ai fait quelques améliorations pour supporter "select all columns except some in 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 cols, utilisez ce sql pour modifier group_concat_max_len

SET @@group_concat_max_len = 2048;
2
répondu hahakubile 2012-06-16 04:55:21

Peut-être que j'ai une solution à de Jan Koritak a souligné la divergence

SELECT CONCAT('SELECT ',
( SELECT GROUP_CONCAT(t.col)
FROM
(
    SELECT CASE
    WHEN COLUMN_NAME = 'eid' THEN NULL
    ELSE COLUMN_NAME
    END AS col 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'
) t
WHERE t.col IS NOT NULL) ,
' FROM employee' );

Tableau :

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

================================

Résultat De La Requête:

'SELECT name_eid,sal FROM employee'
2
répondu Bhavik Shah 2013-07-19 13:27:26

D'accord sur 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 stupide. Allez à la table dans phpmyadmin- > sql - > select, il vide la copie de requête remplacer et fait! :)

2
répondu neelabh 2015-08-07 06:28:47

Si c'est toujours la même colonne, vous pouvez créer une vue qui ne l'a pas.

Sinon, Non, Je ne pense pas.

1
répondu Gareth Simpson 2008-08-12 19:18:13

Vous pouvez utiliser SQL pour générer 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 colonnes du schéma d'informations. Voici un exemple de la ligne de commande Unix.

Substitution de

  • MYSQL avec votre commande mysql
  • TABLE avec le nom de la table
  • EXCLUDEDFIELD avec le nom du 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 manière qu'une seule fois pour construire le la liste des colonnes a exclu 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)

Maintenant, vous pouvez réutiliser la chaîne $column_list dans les requêtes que vous construisez.

1
répondu rplevy 2012-02-18 00:55:52

Je voudrais ajouter un autre point de vue pour résoudre ce problème, spécialement si vous avez un petit nombre de colonnes à supprimer.

Vous pouvez utiliser un outil DB 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, le moyen de le générer est:

Faites un clic droit sur la table - > Envoyer à L'éditeur Sql - > Tout sélectionner Déclaration.

1
répondu H. Paúl Cervera García 2013-12-05 09:51:09

Je suis assez tard pour trouver une réponse à cela, mettez ceci est la façon dont je l'ai toujours fait et franchement, c'est 100 fois mieux et plus propre 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 in order to get all of the column names
    $SQL = "SHOW COLUMNS FROM Table";
        //put all of 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]);
-1
répondu Nick 2013-02-21 21:40:04

Select * est un antipattern SQL. Il ne devrait pas être utilisé dans le code de production pour de nombreuses raisons, y compris:

Cela prend un peu plus de temps à traiter. Quand les choses sont exécutées des millions de fois, ces petits morceaux peuvent avoir de l'importance. 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 à la fois des goulots d'étranglement sur le serveur et le réseau. Si vous avez une jointure intérieure, les chances d'envoyer plus de données que vous avez besoin sont 100%.

Cela provoque des problèmes de maintenance surtout lorsque vous avez ajouté de nouvelles colonnes que vous ne voulez pas voir partout. Si en plus vous avez une nouvelle colonne, vous devrez peut-être faire quelque chose pour l'interface de déterminer quoi faire avec cette colonne.

Il peut casser des vues (Je sais que c'est vrai dans SQl server, il peut ou peut ne pas être vrai dans mysql).

Si quelqu'un est assez stupide pour reconstruire les tables avec les colonnes dans un différent ordre (ce que vous ne devriez pas faire mais cela arrive tout le temps), toutes sortes de code peuvent se casser. Espcially code pour un insert par exemple où soudainement vous mettez la ville dans le champ address_3 parce que sans spécifier, la base de données ne peut aller que dans l'ordre des colonnes. C'est assez mauvais quand les types de données changent mais pire quand les colonnes échangées ont le même type de données parce que vous pouvez aller parfois insérer des données mauvaises qui sont un gâchis à nettoyer. Vous devez vous soucier des données intégrité.

S'il est utilisé dans un insert, il va casser l'insert si une nouvelle colonne est ajoutée dans une table mais pas l'autre.

Il pourrait casser les déclencheurs. Les problèmes de déclenchement peuvent être difficiles à diagnostiquer.

Additionnez tout cela par rapport au temps nécessaire pour ajouter les noms de colonnes (heck vous pouvez même avoir une interface qui vous permet de faire glisser les noms de colonnes (je sais que je fais dans SQL Server, je parie qu'il y a un moyen de le faire est un outil que vous utilisez pour écrire des requêtes mysql.) Nous allons voir ," je peux causer des problèmes de maintenance, je peux causer des problèmes de performance 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."Vraiment juste mettre dans les colonnes spécifiques que vous voulez.

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&keywords=sql+antipatterns

-5
répondu HLGEM 2014-01-16 18:25:30