Выбрать все столбцы, кроме одного в MySQL?

Я пытаюсь использовать оператор select, чтобы получить все столбцы из определенной таблицы MySQL, кроме одного. Есть простой способ сделать это?

РЕДАКТИРОВАТЬ: В этой таблице 53 столбца (НЕ МОЙ ДИЗАЙН)

Ответов (25)

Решение

На самом деле есть способ, для этого вам, конечно же, нужны разрешения ...

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;

Замена <table>, <database> and <columns_to_omit>

Ответ, отправленный Магомедалидом, содержит небольшую проблему:

Код функции замены внутри заменял " <columns_to_delete>, " на "", у этой замены есть проблема, если заменяемое поле является последним в строке concat из-за того, что в последнем поле отсутствует символ-запятая "," и не удаляется из Струна.

Мое предложение:

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>');

Замена <table>, <database> и `

Удаленный столбец заменяется строкой «FIELD_REMOVED», в моем случае это работает, потому что я пытался сохранить память. (Поле, которое я удалял, представляет собой большой двоичный объект размером около 1 МБ)

Мне понравился ответ от, @Mahomedalid кроме этого факта, сообщенного в комментарии от @Bill Karwin . Возможная проблема, поднятая, @Jan Koritak правда, с которой я столкнулся, но я нашел уловку для этого и просто хочу поделиться им здесь для всех, кто сталкивается с проблемой.

мы можем заменить функцию REPLACE предложением where в подзапросе подготовленного оператора следующим образом:

Используя имя моей таблицы и столбца

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;

Итак, это исключает только поле, id но не company_id

Основываясь на ответе @Mahomedalid, я сделал некоторые улучшения для поддержки «выбрать все столбцы, кроме некоторых в 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;

Если у вас много столбцов, используйте этот sql для изменения group_concat_max_len

SET @@group_concat_max_len = 2048;

Я тоже этого хотел, поэтому вместо этого создал функцию.

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)."`";
    }
}

Итак, как это работает: вы вводите таблицу, а затем столбец, который вам не нужен, или как в массиве: array ("id", "name", "anycolumn")

Итак, в select вы можете использовать это так:

mysql_query("SELECT ".$db->getColsExcept('table',array('id','bigtextcolumn'))." FROM table");

или

mysql_query("SELECT ".$db->getColsExcept('table','bigtextcolumn')." FROM table");

Пробуя решения @Mahomedalid и @Junaid, я обнаружил проблему. Так что подумал о том, чтобы поделиться им. Если в имени столбца есть пробелы или дефисы, такие как отметка, запрос завершится ошибкой. Простой обходной путь - использовать обратную кавычку вокруг имен столбцов. Измененный запрос ниже

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;

Если вы хотите исключить значение поля, например, из соображений безопасности / конфиденциальной информации, вы можете получить этот столбец как нулевой.

например

SELECT *, NULL AS salary FROM users

Я согласен с ответом @Mahomedalid, но я не хотел делать что-то вроде подготовленного оператора, и я не хотел вводить все поля, поэтому то, что у меня было, было глупым решением.

Перейдите в таблицу в phpmyadmin-> sql-> select, он выдает запрос: скопировать, заменить и готово! :)

У меня есть предложение, но нет решения. Если некоторые из ваших столбцов имеют большие наборы данных, вам следует попробовать следующие

SELECT *, LEFT(col1, 0) AS col1, LEFT(col2, 0) as col2 FROM table

Если вы используете MySQL Workbench, вы можете щелкнуть правой кнопкой мыши свою таблицу и щелкнуть, Send to sql editor а затем Select All Statement это создаст оператор, в котором перечислены все поля, например:

SELECT `purchase_history`.`id`,
    `purchase_history`.`user_id`,
    `purchase_history`.`deleted_at`
FROM `fs_normal_run_2`.`purchase_history`;
SELECT * FROM fs_normal_run_2.purchase_history;

Теперь вы можете просто удалить те, которые вам не нужны.

Я использую эту работу, хотя она может быть «не по теме» - с использованием mysql workbench и построителя запросов -

  1. Откройте представление столбцов
  2. Shift выберите все столбцы, которые вы хотите в своем запросе (в вашем случае все, кроме одного, что я делаю)
  3. Щелкните правой кнопкой мыши и выберите отправить в редактор SQL-> краткое имя.
  4. Теперь у вас есть список, и вы можете скопировать и вставить запрос куда угодно.

введите описание изображения здесь

Я согласен с тем, что этого недостаточно Select *, если тот, который вам не нужен, как упоминалось в другом месте, является BLOB, вы не хотите, чтобы эти накладные расходы закрались.

Я бы создал представление с необходимыми данными, тогда вы сможете Select * спокойно - если программное обеспечение базы данных их поддерживает. В противном случае поместите огромные данные в другую таблицу.

Насколько мне известно, нет. Вы можете сделать что-то вроде:

SELECT col1, col2, col3, col4 FROM tbl

и вручную выберите нужные столбцы. Однако, если вам нужно много столбцов, вы можете просто сделать:

SELECT * FROM tbl 

и просто игнорируйте то, что вам не нужно.

В вашем конкретном случае я бы предложил:

SELECT * FROM tbl

если вам не нужно всего несколько столбцов. Если вам нужно всего четыре столбца, тогда:

SELECT col3, col6, col45, col 52 FROM tbl

было бы хорошо, но если вы хотите 50 столбцов, тогда любой код, который делает запрос, станет (слишком?) трудным для чтения.

Ты можешь сделать:

SELECT column1, column2, column4 FROM table WHERE whatever

без получения column3, хотя, возможно, вы искали более общее решение?

Если в столбце, который вы не хотели выбирать, было огромное количество данных, и вы не хотели включать его из-за проблем со скоростью, и вы часто выбираете другие столбцы, я бы посоветовал вам создать новую таблицу. с одним полем, которое вы обычно не выбираете ключом к исходной таблице, и удалите это поле из исходной таблицы. Присоединяйтесь к таблицам, когда это дополнительное поле действительно необходимо.

Сначала я подумал, что вы можете использовать регулярные выражения, но, поскольку я читал документы MYSQL, кажется, что вы не можете. На вашем месте я бы использовал другой язык (например, PHP) для создания списка столбцов, которые вы хотите получить, сохранил его в виде строки, а затем использовал бы это для генерации SQL.

Рекомендуется указывать запрашиваемые столбцы, даже если вы запрашиваете все столбцы.

Поэтому я предлагаю вам написать имя каждого столбца в заявлении (за исключением того, который вам не нужен).

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

FROM table

Будет ли в этом случае работать лучше?

CREATE VIEW vwTable
as  
SELECT  
    col1  
    , col2  
    , col3  
    , col..  
    , col53  
FROM table

Вы можете использовать DESCRIBE my_table и использовать результаты этого для динамического создания оператора SELECT.

Хотя я согласен с ответом Томаса (+1;)), я хотел бы добавить предостережение, что я предполагаю, что столбец, который вам не нужен, почти не содержит данных. Если он содержит огромное количество текста, XML или двоичных двоичных объектов, найдите время, чтобы выбрать каждый столбец по отдельности. В противном случае ваша производительность пострадает. Ваше здоровье!

Просто делать

SELECT * FROM table WHERE whatever

Затем опустите столбец на своем любимом языке программирования: php

while (($data = mysql_fetch_array($result, MYSQL_ASSOC)) !== FALSE) {
   unset($data["id"]);
   foreach ($data as $k => $v) { 
      echo"$v,";
   }      
}

Да, хотя это может быть высокий уровень ввода-вывода в зависимости от таблицы, вот обходной путь, который я нашел для этого.

SELECT *
INTO #temp
FROM table

ALTER TABLE #temp DROP COlUMN column_name

SELECT *
FROM #temp

В определениях mysql (руководство) такого нет. Но если у вас действительно большое количество столбцов col1, ... col100,, может быть полезно следующее:

DROP TABLE IF EXISTS temp_tb;
CREATE TEMPORARY TABLE ENGINE=MEMORY temp_tb SELECT * FROM orig_tb;
ALTER TABLE temp_tb DROP col_x;
   #// ALTER TABLE temp_tb DROP col_a, ... , DROP col_z; #// for a few columns to drop
SELECT * FROM temp_tb;

Я согласен с «простым» решением перечислить все столбцы, но это может быть обременительным, а опечатки могут привести к потере времени. Я использую функцию getTableColumns для получения имен моих столбцов, подходящих для вставки в запрос. Тогда все, что мне нужно сделать, это удалить те, которые мне не нужны.

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 [email protected] 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;

Ваш результат возвращает строку с разделителями-запятыми, например ...

col1, col2, col3, col4, ... col53

Моя основная проблема - это множество столбцов, которые я получаю при объединении таблиц. Хотя это не ответ на ваш вопрос (как выбрать все столбцы, кроме определенных из одной таблицы), я думаю, стоит упомянуть, что вы можете указать, чтобы получить все столбцы из определенной таблицы, а не просто указывать . table.

Вот пример того, как это может быть очень полезно:

выберите пользователей. *, phone.meta_value как phone, zipcode.meta_value как zipcode

от пользователей

оставил присоединиться к user_meta как телефон
на ((users.user_id = phone.user_id) И (phone.meta_key = 'phone'))

осталось присоединиться к user_meta как почтовый индекс
на ((users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'zipcode'))

Результатом являются все столбцы из таблицы пользователей и два дополнительных столбца, которые были объединены из метатаблицы.